Initial Release 20/312620/19
authorYoungHun Kim <yh8004.kim@samsung.com>
Wed, 12 Jun 2024 10:16:25 +0000 (19:16 +0900)
committerYoungHun Kim <yh8004.kim@samsung.com>
Wed, 31 Jul 2024 03:28:48 +0000 (12:28 +0900)
Change-Id: Idf763695e21499e52c22355f49f1d0417c40f739

48 files changed:
CMakeLists.txt [new file with mode: 0644]
LICENSE.APLv2 [new file with mode: 0644]
include/RMShm.h [new file with mode: 0644]
include/rm_api.h [new file with mode: 0644]
include/rm_module_api.h [new file with mode: 0644]
include/rm_resource.h [new file with mode: 0644]
include/rm_shm_api.h [new file with mode: 0644]
include/rm_type.h [new file with mode: 0644]
include_internal/RMShmCache.h [new file with mode: 0644]
include_internal/rm_callback.h [new file with mode: 0644]
include_internal/rm_dbus.h [new file with mode: 0644]
include_internal/rm_debug.h [new file with mode: 0644]
include_internal/rm_internal.h [new file with mode: 0644]
include_internal/rm_msg.h [new file with mode: 0644]
packaging/resource-manager.spec [new file with mode: 0644]
resource-manager.manifest [new file with mode: 0644]
resource-manager.pc.in [new file with mode: 0644]
rscmgr-test.manifest [new file with mode: 0644]
src/RMShmCache.cpp [new file with mode: 0644]
src/rm_api.cpp [new file with mode: 0644]
src/rm_callback.cpp [new file with mode: 0644]
src/rm_dbus.cpp [new file with mode: 0644]
src/rm_debug.cpp [new file with mode: 0644]
src/rm_module_api.cpp [new file with mode: 0644]
src/rm_msg.cpp [new file with mode: 0644]
src/rm_shm_api.cpp [new file with mode: 0644]
ut/CMakeLists.txt [new file with mode: 0644]
ut/TCList.dat.in [new file with mode: 0644]
ut/testcase/TCCallbackListener.cpp [new file with mode: 0644]
ut/testcase/TCCallbackListener.h [new file with mode: 0644]
ut/testcase/TCPlayer.cpp [new file with mode: 0644]
ut/testcase/TCPlayer.h [new file with mode: 0644]
ut/testcase/TCResource.cpp [new file with mode: 0644]
ut/testcase/TCResource.h [new file with mode: 0644]
ut/testcase/common.cpp [new file with mode: 0644]
ut/testcase/ut_common.h [new file with mode: 0644]
ut/testcase/ut_main.cpp [new file with mode: 0644]
ut/testcase/ut_tc.cpp [new file with mode: 0644]
ut/testcase/ut_tc_8k.cpp [new file with mode: 0644]
ut/testcase/ut_tc_interaction_sound.cpp [new file with mode: 0644]
ut/testcase/ut_tc_multiview.cpp [new file with mode: 0644]
ut/testcase/ut_tc_multiview_not_support.cpp [new file with mode: 0644]
ut/testcase/ut_tc_resource.cpp [new file with mode: 0644]
ut/testcase/ut_tc_resource_scaler.cpp [new file with mode: 0644]
ut/testcase/ut_tc_video_dec_ai.cpp [new file with mode: 0644]
ut/testcase/ut_tc_video_dec_portrait.cpp [new file with mode: 0644]
ut/testcase/ut_tc_virtual_scaler.cpp [new file with mode: 0644]
ut/testcase/ut_tc_vr360.cpp [new file with mode: 0644]

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..3653527
--- /dev/null
@@ -0,0 +1,93 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6...2.29.2)
+PROJECT(resource-manager CXX C)
+IF(VD_UNIT_TEST)
+    ADD_DEFINITIONS(-DVD_UNIT_TEST)
+ENDIF(VD_UNIT_TEST)
+
+#second modification
+INCLUDE(FindPkgConfig)
+pkg_check_modules(RM_PKGS REQUIRED
+    resource-information
+    dlog
+    glib-2.0
+    gio-unix-2.0
+    capi-system-resource
+)
+
+IF(NOT DEFINED PACKAGE_NAME)
+    SET(PACKAGE_NAME ${PROJECT_NAME})
+ENDIF(NOT DEFINED PACKAGE_NAME)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+IF(NOT DEFINED BINDIR)
+    SET(IMAGEDIR "${PREFIX}/bin")
+ENDIF(NOT DEFINED BINDIR)
+
+SET(CMAKE_EXE_LINKER_FLAGS "-Wl,--as-needed -Wl,--rpath=${LIBDIR}")
+
+SET(INC_PATH ${CMAKE_CURRENT_SOURCE_DIR}/include)
+SET(INC_PATH_INTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/include_internal)
+SET(INC_FILE
+    ${INC_PATH}/rm_api.h
+    ${INC_PATH}/rm_type.h
+    ${INC_PATH}/rm_module_api.h
+    ${INC_PATH}/rm_resource.h
+    ${INC_PATH}/rm_shm_api.h
+    ${INC_PATH}/RMShm.h
+)
+SET(SRC
+    src/rm_api.cpp
+    src/rm_module_api.cpp
+    src/rm_debug.cpp
+    src/rm_callback.cpp
+    src/rm_msg.cpp
+    src/rm_dbus.cpp
+    src/rm_shm_api.cpp
+    src/RMShmCache.cpp
+)
+
+SET(RC_HIJACK "off")
+IF(RC_HIJACK STREQUAL on)
+ADD_DEFINITIONS("-DRC_HIJACK")
+SET(SRC ${SRC}
+    src/rm_rc_hijack.cpp
+)
+ENDIF()
+
+
+MESSAGE("INC_PATH : "${INC_PATH})
+MESSAGE("INC_FILE : "${INC_FILE})
+MESSAGE("SRC : "${SRC})
+
+INCLUDE_DIRECTORIES(${INC_PATH})
+INCLUDE_DIRECTORIES(${INC_PATH_INTERNAL})
+INCLUDE_DIRECTORIES(${RM_PKGS_INCLUDE_DIRS})
+
+#IF(RM_UNIT_TEST)
+#    ADD_SUBDIRECTORY(ut)
+#ENDIF(RM_UNIT_TEST)
+
+ADD_LIBRARY(${PROJECT_NAME} SHARED ${SRC})
+
+CONFIGURE_FILE(resource-manager.pc.in "${CMAKE_CURRENT_SOURCE_DIR}/resource-manager.pc" @ONLY)
+
+FOREACH (flag ${RM_PKGS_CXXFLAGS})
+    SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+
+MESSAGE("RM_PKGS_LDFLAGS : "${RM_PKGS_LDFLAGS})
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${RM_PKGS_LDFLAGS})
+
+SET_TARGET_PROPERTIES(${PROJECT_NAME}
+     PROPERTIES
+     VERSION ${VERSION}
+     SOVERSION ${MAJORVERSION}
+     CLEAN_DIRECT_OUTPUT 1
+)
+# Install
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${LIBDIR})
+INSTALL(FILES ${INC_FILE} DESTINATION ${INCLUDEDIR})
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/resource-manager.pc DESTINATION ${PKGCONFIG_INSTALL_DIR})
+
diff --git a/LICENSE.APLv2 b/LICENSE.APLv2
new file mode 100644 (file)
index 0000000..bbe9d02
--- /dev/null
@@ -0,0 +1,206 @@
+Copyright (c) 2000 - 2011 Samsung Electronics Co., Ltd. All rights reserved.\r
+\r
+                                 Apache License\r
+                           Version 2.0, January 2004\r
+                        http://www.apache.org/licenses/\r
+\r
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\r
+\r
+   1. Definitions.\r
+\r
+      "License" shall mean the terms and conditions for use, reproduction,\r
+      and distribution as defined by Sections 1 through 9 of this document.\r
+\r
+      "Licensor" shall mean the copyright owner or entity authorized by\r
+      the copyright owner that is granting the License.\r
+\r
+      "Legal Entity" shall mean the union of the acting entity and all\r
+      other entities that control, are controlled by, or are under common\r
+      control with that entity. For the purposes of this definition,\r
+      "control" means (i) the power, direct or indirect, to cause the\r
+      direction or management of such entity, whether by contract or\r
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the\r
+      outstanding shares, or (iii) beneficial ownership of such entity.\r
+\r
+      "You" (or "Your") shall mean an individual or Legal Entity\r
+      exercising permissions granted by this License.\r
+\r
+      "Source" form shall mean the preferred form for making modifications,\r
+      including but not limited to software source code, documentation\r
+      source, and configuration files.\r
+\r
+      "Object" form shall mean any form resulting from mechanical\r
+      transformation or translation of a Source form, including but\r
+      not limited to compiled object code, generated documentation,\r
+      and conversions to other media types.\r
+\r
+      "Work" shall mean the work of authorship, whether in Source or\r
+      Object form, made available under the License, as indicated by a\r
+      copyright notice that is included in or attached to the work\r
+      (an example is provided in the Appendix below).\r
+\r
+      "Derivative Works" shall mean any work, whether in Source or Object\r
+      form, that is based on (or derived from) the Work and for which the\r
+      editorial revisions, annotations, elaborations, or other modifications\r
+      represent, as a whole, an original work of authorship. For the purposes\r
+      of this License, Derivative Works shall not include works that remain\r
+      separable from, or merely link (or bind by name) to the interfaces of,\r
+      the Work and Derivative Works thereof.\r
+\r
+      "Contribution" shall mean any work of authorship, including\r
+      the original version of the Work and any modifications or additions\r
+      to that Work or Derivative Works thereof, that is intentionally\r
+      submitted to Licensor for inclusion in the Work by the copyright owner\r
+      or by an individual or Legal Entity authorized to submit on behalf of\r
+      the copyright owner. For the purposes of this definition, "submitted"\r
+      means any form of electronic, verbal, or written communication sent\r
+      to the Licensor or its representatives, including but not limited to\r
+      communication on electronic mailing lists, source code control systems,\r
+      and issue tracking systems that are managed by, or on behalf of, the\r
+      Licensor for the purpose of discussing and improving the Work, but\r
+      excluding communication that is conspicuously marked or otherwise\r
+      designated in writing by the copyright owner as "Not a Contribution."\r
+\r
+      "Contributor" shall mean Licensor and any individual or Legal Entity\r
+      on behalf of whom a Contribution has been received by Licensor and\r
+      subsequently incorporated within the Work.\r
+\r
+   2. Grant of Copyright License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      copyright license to reproduce, prepare Derivative Works of,\r
+      publicly display, publicly perform, sublicense, and distribute the\r
+      Work and such Derivative Works in Source or Object form.\r
+\r
+   3. Grant of Patent License. Subject to the terms and conditions of\r
+      this License, each Contributor hereby grants to You a perpetual,\r
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\r
+      (except as stated in this section) patent license to make, have made,\r
+      use, offer to sell, sell, import, and otherwise transfer the Work,\r
+      where such license applies only to those patent claims licensable\r
+      by such Contributor that are necessarily infringed by their\r
+      Contribution(s) alone or by combination of their Contribution(s)\r
+      with the Work to which such Contribution(s) was submitted. If You\r
+      institute patent litigation against any entity (including a\r
+      cross-claim or counterclaim in a lawsuit) alleging that the Work\r
+      or a Contribution incorporated within the Work constitutes direct\r
+      or contributory patent infringement, then any patent licenses\r
+      granted to You under this License for that Work shall terminate\r
+      as of the date such litigation is filed.\r
+\r
+   4. Redistribution. You may reproduce and distribute copies of the\r
+      Work or Derivative Works thereof in any medium, with or without\r
+      modifications, and in Source or Object form, provided that You\r
+      meet the following conditions:\r
+\r
+      (a) You must give any other recipients of the Work or\r
+          Derivative Works a copy of this License; and\r
+\r
+      (b) You must cause any modified files to carry prominent notices\r
+          stating that You changed the files; and\r
+\r
+      (c) You must retain, in the Source form of any Derivative Works\r
+          that You distribute, all copyright, patent, trademark, and\r
+          attribution notices from the Source form of the Work,\r
+          excluding those notices that do not pertain to any part of\r
+          the Derivative Works; and\r
+\r
+      (d) If the Work includes a "NOTICE" text file as part of its\r
+          distribution, then any Derivative Works that You distribute must\r
+          include a readable copy of the attribution notices contained\r
+          within such NOTICE file, excluding those notices that do not\r
+          pertain to any part of the Derivative Works, in at least one\r
+          of the following places: within a NOTICE text file distributed\r
+          as part of the Derivative Works; within the Source form or\r
+          documentation, if provided along with the Derivative Works; or,\r
+          within a display generated by the Derivative Works, if and\r
+          wherever such third-party notices normally appear. The contents\r
+          of the NOTICE file are for informational purposes only and\r
+          do not modify the License. You may add Your own attribution\r
+          notices within Derivative Works that You distribute, alongside\r
+          or as an addendum to the NOTICE text from the Work, provided\r
+          that such additional attribution notices cannot be construed\r
+          as modifying the License.\r
+\r
+      You may add Your own copyright statement to Your modifications and\r
+      may provide additional or different license terms and conditions\r
+      for use, reproduction, or distribution of Your modifications, or\r
+      for any such Derivative Works as a whole, provided Your use,\r
+      reproduction, and distribution of the Work otherwise complies with\r
+      the conditions stated in this License.\r
+\r
+   5. Submission of Contributions. Unless You explicitly state otherwise,\r
+      any Contribution intentionally submitted for inclusion in the Work\r
+      by You to the Licensor shall be under the terms and conditions of\r
+      this License, without any additional terms or conditions.\r
+      Notwithstanding the above, nothing herein shall supersede or modify\r
+      the terms of any separate license agreement you may have executed\r
+      with Licensor regarding such Contributions.\r
+\r
+   6. Trademarks. This License does not grant permission to use the trade\r
+      names, trademarks, service marks, or product names of the Licensor,\r
+      except as required for reasonable and customary use in describing the\r
+      origin of the Work and reproducing the content of the NOTICE file.\r
+\r
+   7. Disclaimer of Warranty. Unless required by applicable law or\r
+      agreed to in writing, Licensor provides the Work (and each\r
+      Contributor provides its Contributions) on an "AS IS" BASIS,\r
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\r
+      implied, including, without limitation, any warranties or conditions\r
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\r
+      PARTICULAR PURPOSE. You are solely responsible for determining the\r
+      appropriateness of using or redistributing the Work and assume any\r
+      risks associated with Your exercise of permissions under this License.\r
+\r
+   8. Limitation of Liability. In no event and under no legal theory,\r
+      whether in tort (including negligence), contract, or otherwise,\r
+      unless required by applicable law (such as deliberate and grossly\r
+      negligent acts) or agreed to in writing, shall any Contributor be\r
+      liable to You for damages, including any direct, indirect, special,\r
+      incidental, or consequential damages of any character arising as a\r
+      result of this License or out of the use or inability to use the\r
+      Work (including but not limited to damages for loss of goodwill,\r
+      work stoppage, computer failure or malfunction, or any and all\r
+      other commercial damages or losses), even if such Contributor\r
+      has been advised of the possibility of such damages.\r
+\r
+   9. Accepting Warranty or Additional Liability. While redistributing\r
+      the Work or Derivative Works thereof, You may choose to offer,\r
+      and charge a fee for, acceptance of support, warranty, indemnity,\r
+      or other liability obligations and/or rights consistent with this\r
+      License. However, in accepting such obligations, You may act only\r
+      on Your own behalf and on Your sole responsibility, not on behalf\r
+      of any other Contributor, and only if You agree to indemnify,\r
+      defend, and hold each Contributor harmless for any liability\r
+      incurred by, or claims asserted against, such Contributor by reason\r
+      of your accepting any such warranty or additional liability.\r
+\r
+   END OF TERMS AND CONDITIONS\r
+\r
+   APPENDIX: How to apply the Apache License to your work.\r
+\r
+      To apply the Apache License to your work, attach the following\r
+      boilerplate notice, with the fields enclosed by brackets "[]"\r
+      replaced with your own identifying information. (Don't include\r
+      the brackets!)  The text should be enclosed in the appropriate\r
+      comment syntax for the file format. We also recommend that a\r
+      file or class name and description of purpose be included on the\r
+      same "printed page" as the copyright notice for easier\r
+      identification within third-party archives.\r
+\r
+   Copyright [yyyy] [name of copyright owner]\r
+\r
+   Licensed under the Apache License, Version 2.0 (the "License");\r
+   you may not use this file except in compliance with the License.\r
+   You may obtain a copy of the License at\r
+\r
+       http://www.apache.org/licenses/LICENSE-2.0\r
+\r
+   Unless required by applicable law or agreed to in writing, software\r
+   distributed under the License is distributed on an "AS IS" BASIS,\r
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+   See the License for the specific language governing permissions and\r
+   limitations under the License.\r
+\r
+\r
+\r
diff --git a/include/RMShm.h b/include/RMShm.h
new file mode 100644 (file)
index 0000000..bc21e7d
--- /dev/null
@@ -0,0 +1,280 @@
+/*
+ * 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 __RM_SHM_H__
+#define __RM_SHM_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+* @brief Shared memory object type
+*/
+typedef enum {
+       RM_SHM_OBJ_PLAYER = 0, /**< the object including <player id, app id> pair */
+       RM_SHM_OBJ_SCALER, /**< the object including <device id, CShmScaler> pair */
+       RM_SHM_OBJ_AUDIO_OUT /**< the object including <device id, CShmResource> pair */
+} rm_shm_object_id;
+
+/**
+ * @vd_noapi
+ * @brief This class is for the shared memory between resource-manager and rscmgr-service
+ * @remark Please do not use this in other package.
+ */
+class CShmResource
+{
+public:
+       /**
+        * @vd_noapi
+        * @brief Construct an instance of CShmResource class
+        * @param[in] device_id device id
+        * @param[in] state resource state
+        * @param[in] player_id player id using this resource
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       CShmResource(): device_id_(-1), state_(-1), player_id_(-1) {}
+
+       /**
+        * @vd_noapi
+        * @brief Construct an instance of CShmResource class
+        * @param[in] device_id device id
+        * @param[in] state resource state
+        * @param[in] player_id player id using this resource
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       CShmResource(const int device_id, const int state, const int player_id): device_id_(device_id), state_(state), player_id_(player_id) {}
+
+       /**
+        * @vd_noapi
+        * @brief Destruct an instance of CShmResource class
+        * @param None
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       ~CShmResource() = default;
+
+       /**
+        * @vd_noapi
+        * @brief Get device id
+        * @param None
+        * @return device id
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       int GetDeviceID(void) { return device_id_; }
+
+       /**
+        * @vd_noapi
+        * @brief Set resource state
+        * @param[in] state resource state
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       void SetState(const int state) { state_ = state; }
+
+       /**
+        * @vd_noapi
+        * @brief Get resource state
+        * @param None
+        * @return resource state
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       int GetState(void) { return state_; }
+
+       /**
+        * @vd_noapi
+        * @brief Set player id using this resource
+        * @param[in] player_id player id
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       void SetPlayerID(const int player_id) { player_id_ = player_id; }
+
+       /**
+        * @vd_noapi
+        * @brief Get player id
+        * @param None
+        * @return player id
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       int GetPlayerID(void) { return player_id_; }
+
+protected:
+       /**
+        * @vd_noapi
+        * @brief Set device id
+        * @param None
+        * @return device id
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       void SetDeviceID(const int device_id) { device_id_ = device_id; }
+
+private:
+       int device_id_;
+       int state_;
+       int player_id_;
+};
+
+/**
+ * @vd_noapi
+ * @brief This class is for the shared memory between resource-manager and rscmgr-service
+ * @remark Please do not use this in other package.
+ */
+class CShmScaler : public CShmResource
+{
+public:
+       /**
+        * @vd_noapi
+        * @brief Construct an instance of CShmScaler class
+        * @param[in] device_id device id of scaler
+        * @param[in] state resource state of scaler
+        * @param[in] zone_id multiview zone id of scaler
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       CShmScaler(const int device_id, const int state, const int zone_id): zone_id_(zone_id), virtual_id_(-1) { CShmResource::SetDeviceID(device_id); CShmResource::SetState(state); }
+
+       /**
+        * @vd_noapi
+        * @brief Destruct an instance of CShmScaler class
+        * @param None
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       ~CShmScaler() = default;
+
+       /**
+        * @vd_noapi
+        * @brief Set multiview zone id
+        * @param[in] id multiview zone id
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       void SetZoneID(const int id) { zone_id_ = id; }
+
+       /**
+        * @vd_noapi
+        * @brief Get multiview zone id
+        * @param None
+        * @return multiview zone id
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       int GetZoneID(void) { return zone_id_; }
+
+       /**
+        * @vd_noapi
+        * @brief Set virtual id
+        * @param[in] id virtual id
+        * @return None
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       void SetVirtualID(const int id) { virtual_id_ = id; }
+
+       /**
+        * @vd_noapi
+        * @brief Get virtual id
+        * @param None
+        * @return virtual id
+        * @pre None
+        * @post None
+        * @exception None
+        * @remark
+        * \li This is supposed to be used by resource-manager and rscmgr-service
+        * \li Do not use in other package
+        */
+       int GetVirtualID(void) { return virtual_id_; }
+
+private:
+       int zone_id_;
+       int virtual_id_;
+};
+
+#ifdef __cplusplus
+}
+#endif
+#endif //__RM_SHM_H__
diff --git a/include/rm_api.h b/include/rm_api.h
new file mode 100644 (file)
index 0000000..60167a7
--- /dev/null
@@ -0,0 +1,117 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_API_H__\r
+#define __RM_API_H__\r
+\r
+#include <rm_type.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @brief                               Register a player\r
+ * @param[in] cb                        callback to receive resource conflict event\r
+ * @param[in] data                      user data passed to cb\r
+ * @param[out] handle                   handle got from resource manager\r
+ * @param[in] consumer_info             player information such as player type, priority, window id and so on\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               None\r
+ * @exception                                                  None\r
+ */\r
+int rm_register(rm_resource_cb cb, void *data, int *handle, rm_consumer_info *consumer_info);\r
+\r
+/**\r
+ * @brief                               Unregister a player\r
+ * @param[in] handle                    handle to unregister\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               handle is deactivated.\n\r
+ *                                                                             All resources which have been allocated to handle are released\r
+ * @exception                                                  None\r
+ */\r
+int rm_unregister(int handle);\r
+\r
+/**\r
+ * @brief                               request to allocate resources\r
+ * @param[in] handle                    handle to which resources are to be allocated\r
+ * @param[in] requests                                 Resource information to allocate\r
+ *         can request N resources simultaneously\r
+ *         Ex. {Resource A, Resource A, Resouce B,¡¦. Resouce N}\r
+ * @param[out] return_devices          allocated Device ID. Caller needs to release memory allocated by Resource Manager\r
+ *                                      !!IMPORTANT!!!\r
+ *                                      The member of structure(device_node, omx_comp_name) must be freed by API caller side.\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               None\r
+ * @exception                                                  None\r
+ */\r
+int rm_allocate_resources(int handle, const rm_category_request_s *requests, rm_device_return_s *return_devices);\r
+\r
+/**\r
+ * @brief                               request to release resources\r
+ * @param[in] handle                    handle to which resources have been allocated\r
+ * @param[in] requests                             device information to release\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               None\r
+ * @exception                                                  None\r
+ */\r
+int rm_deallocate_resources(int handle, rm_device_request_s *requests);\r
+\r
+/**\r
+ * @brief                               Query resource state\r
+ * @param[in] handle                    handle gotten from rm_register()\r
+ * @param[in] query_type                query type such as allocation\r
+ * @param[in] requests                  Resource information to query\r
+ * @param[out] query_result             0: not available\r
+ *                                      1: available\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               None\r
+ * @exception                                                  None\r
+ */\r
+int rm_query(int handle, rm_query_type_e query_type, rm_category_request_s *requests, int *query_result);\r
+\r
+/**\r
+ * @brief                               Set priority of handle\r
+ * @param[in] handle                    handle to change priority\r
+ * @param[in] priority                  new priority of handle\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               None\r
+ * @exception                                                  None\r
+ */\r
+int rm_set_priority(int handle, int priority);\r
+\r
+/**\r
+ * @brief                               Set application id of handle\r
+ * @param[in] handle                    handle to change application id\r
+ * @param[in] app_id                   new application id of handle\r
+ * @return int failure reason\r
+ * @pre                                                                        None\r
+ * @post                                                               None\r
+ * @exception                                                  None\r
+ */\r
+int rm_set_app_id(int handle, char *app_id);\r
+\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif // __RM_API_H__
\ No newline at end of file
diff --git a/include/rm_module_api.h b/include/rm_module_api.h
new file mode 100644 (file)
index 0000000..05ab413
--- /dev/null
@@ -0,0 +1,653 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_MODULE_API_H__\r
+#define __RM_MODULE_API_H__\r
+\r
+#include <rm_type.h>\r
+#include <rm_resource.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @brief The resource category option to select a resource\r
+ * @remark This is supposed to be used by the resource center only\r
+ * @version 3.0\r
+ */\r
+typedef enum {\r
+       RM_FORCE_TO_MAIN = (0x1 << 27),\r
+       RM_FORCE_TO_SUB = (0x1 << 26)\r
+} rm_device_request_e;\r
+\r
+/**\r
+ * @brief The resource collection\r
+ * @remark This is supposed to be used by the resource center only\r
+ * @version 4.0\r
+ */\r
+typedef enum {\r
+       RM_RSC_COLLECTION_MAIN = 0,             /**< main resources */\r
+       RM_RSC_COLLECTION_ACTIVE_VIDEO_DECODER, /**< active video decoders */\r
+       RM_RSC_COLLECTION_AUDIO                 /**< audio resources (audio decoder, audio out) */\r
+} rm_rsc_collection_e;\r
+\r
+/**\r
+ * @brief The audio out type\r
+ * @remark This is supposed to be used by the resource center only\r
+ * @version 3.0\r
+ */\r
+typedef enum {\r
+       RM_AUDIO_OUT_NONE = 0,\r
+       RM_AUDIO_OUT_MAIN = 0x1,\r
+       RM_AUDIO_OUT_SUB = 0x2,\r
+} rm_audio_out_e;\r
+\r
+/**\r
+ * @brief The video sampling format\r
+ * @remark This is used as a return value of rm_resource_get_max_sampling_format()\r
+ * @version 3.0\r
+ */\r
+typedef enum {\r
+       RM_SAMPLING_FORMAT_ARGB = 0, /**< ARGB */\r
+       RM_SAMPLING_FORMAT_420, /**< YUV420 */\r
+       RM_SAMPLING_FORMAT_422, /**< YUV422 */\r
+       RM_SAMPLING_FORMAT_444 /**< YUV444 */\r
+} rm_sampling_format_e;\r
+\r
+/**\r
+ * @brief The video resolution\r
+ * @remark This is used as a return value of rm_resource_get_max_resolution()\r
+ * @version 3.0\r
+ */\r
+typedef enum {\r
+       RM_RESOLUTION_HD = 0, /**< HD */\r
+       RM_RESOLUTION_FHD, /**< FHD */\r
+       RM_RESOLUTION_4K, /**< 4K */\r
+       RM_RESOLUTION_8K /**< 8K */\r
+} rm_resolution_e;\r
+\r
+/**\r
+ * @brief Get current resource state\r
+ * @param[in] rsc_id resource id\r
+ * @param[out] state current resource state\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @version 3.0\r
+ * @exception None\r
+ */\r
+int rm_get_resource_state(int rsc_id, rm_resource_state_e *state);\r
+\r
+/**\r
+ * @brief Get the resource list handle of video scaler\r
+ * @param[out] list resource list handle\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @version 3.0\r
+ * @exception None\r
+ * @remark\r
+ * \li This API is supposed to be used by the resource center for internal use\r
+ * \li Please do not use for other purpose\r
+ * \li The returned list  must be freed by rm_free_resource_list() after use\r
+ */\r
+int rm_get_scaler_state(rm_resource_list_h *list);\r
+\r
+/**\r
+ * @brief Called when scaler state is changed\r
+ * @param[out] scalers Scaler list\r
+ * @param[out] data The user data passed from the callback registration function\r
+ * @pre None\r
+ * @post None\r
+ * @version 3.0\r
+ */\r
+typedef void (*scaler_state_change_cb)(rm_resource_list_h scalers, void *data);\r
+\r
+/**\r
+ * @brief Register a callback to observe scaler state change\r
+ * @details Once there is any state change of scaler, the registered callback will be invoked.\r
+ * @param[in] cb The callback function to register\r
+ * @param[in] data The user data to be passed to the callback function\r
+ * @return @c RM_OK on success,\r
+ *         otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be used by the resource center for internal use\r
+ * \li Please do not use for other purpose\r
+ */\r
+int rm_subscribe_scaler_state_change(scaler_state_change_cb cb, void *data);\r
+\r
+/**\r
+ * @brief Unregister a callback which had been added to observe scaler state change\r
+ * @param[in] cb The callback function to unregister\r
+ * @return @c RM_OK on success,\r
+ *         otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be used by the resource center for internal use\r
+ * \li Please do not use for other purpose\r
+ */\r
+int rm_unsubscribe_scaler_state_change(scaler_state_change_cb cb);\r
+\r
+/**\r
+ * @brief Get virtual id of scaler\r
+ * @param[in] scaler scaler handle\r
+ * @return virtual id of scaler\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be used by the resource center for internal use\r
+ * \li Please do not use for other purpose\r
+ */\r
+int rm_scaler_get_virtual_id(rm_resource_h scaler);\r
+\r
+/**\r
+ * @brief Get source id of scaler\r
+ * @param[in] scaler scaler handle\r
+ * @return source id of scaler\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be used by the resource center for internal use\r
+ * \li Please do not use for other purpose\r
+ */\r
+int rm_scaler_get_source_id(rm_resource_h scaler);\r
+\r
+/**\r
+ * @brief Called when a resource state is changed\r
+ * @param[out] state The resource state handle\r
+ * @param[out] data The user data passed from the callback registration function\r
+ * @pre None\r
+ * @post None\r
+ * @version 3.0\r
+ * @remarks The data of the resource state handle can be accessed by the following APIs.\r
+ *          rm_rsc_state_get_category()\r
+ *          rm_rsc_state_get_id()\r
+ *          rm_rsc_state_get_state()\r
+ *          The passed resource state handle is valid in resource_state_change_cb() only.\r
+ *          In other words, the passed resource state handle is freed once resource_state_change_cb() returns.\r
+ *          Thus, need a deep copy in case information of the resource state handle is required outside of resource_state_change_cb().\r
+ */\r
+typedef void (*resource_state_change_cb)(rm_resource_state_h state, void *data);\r
+\r
+/**\r
+ * @brief Register a callback to observe resource state change\r
+ * @details Once there is state change of a resource included in passed category, the registered callback will be invoked.\r
+ * @param[in] category category id to observe\r
+ * @param[in] cb The callback function to register\r
+ * @param[in] data The user data to be passed to the callback function\r
+ * @return @c RM_OK on success,\r
+ *         otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_subscribe_resource_state_change(rm_rsc_category_e category, resource_state_change_cb cb, void *data);\r
+\r
+/**\r
+ * @brief Unregister a callback which had been added to observe resource state change\r
+ * @param[in] category category id to stop to observe\r
+ * @param[in] cb The callback function to unregister\r
+ * @return @c RM_OK on success,\r
+ *         otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_unsubscribe_resource_state_change(rm_rsc_category_e category, resource_state_change_cb cb);\r
+\r
+/**\r
+ * @brief Get category id of the state changed resource\r
+ * @param[in] state The state changed resource handle\r
+ * @return category id of the state changed resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_rsc_state_get_category(rm_resource_state_h state);\r
+\r
+/**\r
+ * @brief Get device id of the state changed resource\r
+ * @param[in] state The state changed resource handle\r
+ * @return device id of the state changed resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_rsc_state_get_device_id(rm_resource_state_h state);\r
+\r
+/**\r
+ * @brief Get state of the state changed resource\r
+ * @param[in] state The state changed resource handle\r
+ * @return state of the state changed resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_rsc_state_get_state(rm_resource_state_h state);\r
+\r
+/**\r
+ * @brief Get consumer id of the state changed resource\r
+ * @param[in] state The state changed resource handle\r
+ * @return consumer id of the state changed resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_rsc_state_get_consumer_id(rm_resource_state_h state);\r
+\r
+/**\r
+ * @brief Get app id of the state changed resource\r
+ * @param[in] state The state changed resource handle\r
+ * @return app id of the state changed resource handle on success,\r
+ *         otherwise NULL\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+char *rm_rsc_state_get_app_id(rm_resource_state_h state);\r
+\r
+struct rm_conflict_resource;\r
+/**\r
+ * @brief The conflicted resource handle\r
+ */\r
+typedef struct rm_conflict_resource *rm_conflict_resource_h;\r
+\r
+/**\r
+ * @brief Called when a resource conflict occurs\r
+ * @param[out] resource The conflicted resource handle\r
+ * @param[out] data The user data passed from the callback registration function\r
+ * @pre None\r
+ * @post None\r
+ * @version 3.0\r
+ * @remarks The data of the conflicted resource handle can be accessed by the following APIs.\r
+ *          rm_conflict_get_category_id()\r
+ *          rm_conflict_get_device_id()\r
+ *          rm_conflict_get_consumer_id()\r
+ *          rm_conflict_get_app_id()\r
+ *          The passed conflicted resource handle is valid in rm_conflict_event_cb() only.\r
+ *          In other words, the passed conflicted resource handle is freed once rm_conflict_event_cb() returns.\r
+ *          Thus, need a deep copy in case information of the conflicted resource handle is required outside of rm_conflict_event_cb().\r
+ */\r
+typedef void (*rm_conflict_event_cb)(rm_conflict_resource_h resource, void *data);\r
+\r
+/**\r
+ * @brief Register a callback to observe resource conflict event.\r
+ * @details Once there is a resource conflict, the registered callback will be invoked.\r
+ * @param[in] cb The callback function to add\r
+ * @param[in] data The user data to be passed to the callback function\r
+ * @return @c RM_OK on success,\r
+ *         otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_subscribe_resource_conflict_event(rm_conflict_event_cb cb, void *data);\r
+\r
+/**\r
+ * @brief Unregister a callback which had been added to observe resource conflict event.\r
+ * @param[in] cb The callback function to remove\r
+ * @return @c RM_OK on success,\r
+ *         otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_unsubscribe_resource_conflict_event(rm_conflict_event_cb cb);\r
+\r
+/**\r
+ * @brief Gets resource category id of the conflicted resource\r
+ * @param[in] rsc The conflicted resource handle\r
+ * @return resource category id of the conflicted resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_conflict_get_category_id(rm_conflict_resource_h rsc);\r
+\r
+/**\r
+ * @brief Gets device id of the conflicted resource\r
+ * @param[in] rsc The conflicted resource handle\r
+ * @return device id of the conflicted resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_conflict_get_device_id(rm_conflict_resource_h rsc);\r
+\r
+/**\r
+ * @brief Gets consumer id of the conflicted resource\r
+ * @param[in] rsc The conflicted resource handle\r
+ * @return consumer id of the conflicted resource handle on success,\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @remarks The consumer id is an unique id which is assigned to a player as a result of rm_register().\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_conflict_get_consumer_id(rm_conflict_resource_h rsc);\r
+\r
+/**\r
+ * @brief Gets application id of the conflicted resource\r
+ * @param[in] rsc The conflicted resource handle\r
+ * @return application id of the conflicted resource on success\r
+ *         otherwise NULL\r
+ * @pre None\r
+ * @post None\r
+ * @remarks In case any application id is not set by a player, NULL can be returned on success.\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+const char *rm_conflict_get_app_id(rm_conflict_resource_h rsc);\r
+\r
+/**\r
+ * @brief Gets multiview zone id of the consumer that needs to release the conflicted resource\r
+ * @param[in] rsc The conflicted resource handle\r
+ * @return multiview zone id in case the conflicted resource is allocated to a multiview zone\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_conflict_get_multiview_zone_id_consumer(rm_conflict_resource_h rsc);\r
+\r
+/**\r
+ * @brief Gets multiview zone id of the requester that caused this resource conflict\r
+ * @param[in] rsc The conflicted resource handle\r
+ * @return multiview zone id in case the requester is placed to a multiview zone\r
+ *         otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ */\r
+int rm_conflict_get_multiview_zone_id_requester(rm_conflict_resource_h rsc);\r
+\r
+/**\r
+ * @brief Unmask category option bits\r
+ * @param[in] category resource category to unmask\r
+ * @return unmasked category id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ */\r
+int rm_unmask_category_options(int category);\r
+\r
+/**\r
+ * @brief Find real device id which is mapped to virtual device id\r
+ * @param[in] virtual_id virtual device id\r
+ * @return positive real resource id on success, negative value on failure\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is available for the scaler device supporting virtual device.\r
+ */\r
+int rm_find_device_id(int virtual_id);\r
+\r
+/**\r
+ * @brief Swap two resources\r
+ * @param[in] device_id_a device id to swap\r
+ * @param[in] device_id_b device id to swap\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is available for the scaler device supporting virtual device.\r
+ * \li This API is supposed to be called by the resource center only\r
+ */\r
+int rm_swap_resources(int device_id_a, int device_id_b);\r
+\r
+/**\r
+ * @brief Swap two resources asynchronously\r
+ * @param[in] device_id_a device id to swap\r
+ * @param[in] device_id_b device id to swap\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.1\r
+ * @remark\r
+ * \li This API is available for the scaler device supporting virtual device.\r
+ * \li This API is supposed to be called by the resource center only\r
+ */\r
+int rm_swap_resources_async(int device_id_a, int device_id_b);\r
+\r
+/**\r
+ * @brief Restore resources that have been swapped by rm_swap_resources()\r
+ * @param[in] category resource category to restore\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ */\r
+int rm_restore_resources(int category);\r
+\r
+/**\r
+ * @brief Get the resource list handle of resource collection\r
+ * @param[in] collection resource collection\r
+ * @param[out] list resource list handle\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li The returned list  must be freed by rm_free_resource_list() after use\r
+ */\r
+int rm_get_resource_collection_state(rm_rsc_collection_e collection, rm_resource_list_h *list);\r
+\r
+/**\r
+ * @brief Get application id of handle\r
+ * @param[in] handle player handle returned by rm_register()\r
+ * @param[out] app_id application id of handle\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_get_app_id(int handle, char**app_id);\r
+\r
+/**\r
+ * @brief Get active audio out resources being used by handle\r
+ * @param[in] handle player handle returned by rm_register()\r
+ * @return positive value masked with rm_audio_out_e on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_get_active_audio_out(int handle);\r
+\r
+/**\r
+ * @brief Get hw id of scaler assigned to passed multiview zone id\r
+ * @param[in] zone_id multiview zone id\r
+ * @param[out] id The hw id of scaler assigned to passed multiview zone id,\r
+ * @return positive value on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_get_scaler_hw_id(int zone_id, int *id);\r
+\r
+/**\r
+ * @brief Notify current resource policy\r
+ * @param[in] policy resource policy\r
+ * @return positive value on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.1\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_notify_resource_policy(int policy);\r
+\r
+/**\r
+ * @brief Notify application's zone info in multiview\r
+ * @param[in] app_id application id\r
+ * @param[in] zone_id zone id\r
+ * @return positive value on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 5.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_notify_app_zone_info_async(const char *app_id, int zone_id);\r
+\r
+/**\r
+ * @brief Reclaim all resources allocated to the handle\r
+ * @param[in] handle player handle returned by rm_register()\r
+ * @return positive value on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 4.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_reclaim_resources(int handle);\r
+\r
+/**\r
+ * @brief Reclaim all resources allocated to the application\r
+ * @param[in] app_id application id\r
+ * @param[in] notify true : notify resource conflict, false : skip to notify\r
+ * @return positive value on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 5.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_reclaim_app_resources(const char *app_id, const bool notify);\r
+\r
+\r
+/**\r
+ * @brief Reclaim all resources allocated to the application asynchronously\r
+ * @param[in] app_id application id\r
+ * @param[in] notify true : notify resource conflict, false : skip to notify\r
+ * @return positive value on success, otherwise negative value\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 5.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use other purpose\r
+ */\r
+int rm_reclaim_app_resources_async(const char *app_id, const bool notify);\r
+\r
+/**\r
+ * @brief Reclaim all video decoders allocated to applications other than requester\r
+ * @param[in] requester application id of the requester\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 5.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the camera framework only\r
+ * \li Do not use for other purpose\r
+ */\r
+int rm_reclaim_video_decoders(const char *requester);\r
+\r
+/**\r
+ * @brief Check if the handle is valid or not\r
+ * @param[in] handle player handle returned by rm_register()\r
+ * @return true : player handle is valid, false : player handle is invalid\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 6.0\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use for other purpose\r
+ */\r
+bool rm_active_player(const int handle);\r
+\r
+/**\r
+ * @brief Check if the player is in progress of reclaiming resource\r
+ * @param[in] handle player handle returned by rm_register()\r
+ * @return true : reclaim is in progress against the player, false : reclaim is not in progress against the player\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li This API is supposed to be called by the resource center only\r
+ * \li Do not use for other purpose\r
+ */\r
+bool rm_reclaimed_player(const int handle);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif //__RM_MODULE_API_H__\r
diff --git a/include/rm_resource.h b/include/rm_resource.h
new file mode 100644 (file)
index 0000000..2e9adad
--- /dev/null
@@ -0,0 +1,326 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_RESOURCE_H__\r
+#define __RM_RESOURCE_H__\r
+\r
+#include <rm_type.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+/**\r
+ * @brief Create a resource list handle\r
+ * @param None\r
+ * @return resource list handle on success, otherwise NULL\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li The returned list  must be freed by rm_free_resource_list() after use\r
+ */\r
+rm_resource_list_h rm_resource_list_create(void);\r
+\r
+/**\r
+ * @brief Get the resource list handle of resource category\r
+ * @param[in] category resource category\r
+ * @param[out] list resource list handle\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li The returned list  must be freed by rm_free_resource_list() after use\r
+ */\r
+int rm_get_resource_list(rm_rsc_category_e category, rm_resource_list_h *list);\r
+\r
+/**\r
+ * @brief Free resource list handle\r
+ * @param[in] list resource list handle\r
+ * @return None\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li The elements in the list will be freed as well\r
+ */\r
+void rm_free_resource_list(rm_resource_list_h list);\r
+\r
+/**\r
+ * @brief Append a resource to the resource list\r
+ * @param[in] list resource list handle\r
+ * @param[out] resource resource handle\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_list_append(rm_resource_list_h list, rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get next resource handle from resource list handle\r
+ * @param[in] list resource list handle\r
+ * @return next resource handle\r
+ *         In case there is no next resource handle or error, returns NULL\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+rm_resource_h rm_resource_list_get_next(rm_resource_list_h list);\r
+\r
+/**\r
+ * @brief Get previous resource handle from resource list handle\r
+ * @param[in] list resource list handle\r
+ * @return previous resource handle\r
+ *         In case there is no previous resource handle or error, returns NULL\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+rm_resource_h rm_resource_list_get_prev(rm_resource_list_h list);\r
+\r
+/**\r
+ * @brief Get first resource handle from resource list handle\r
+ * @param[in] list resource list handle\r
+ * @return first resource handle\r
+ *         In case there is no previous resource handle or error, returns NULL\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+rm_resource_h rm_resource_list_get_first(rm_resource_list_h list);\r
+\r
+/**\r
+ * @brief Get last resource handle from resource list handle\r
+ * @param[in] list resource list handle\r
+ * @return last resource handle\r
+ * @pre In case there is no last resource handle or error, returns NULL\r
+ * @post None\r
+ * @exception None\r
+ */\r
+rm_resource_h rm_resource_list_get_last(rm_resource_list_h list);\r
+\r
+/**\r
+ * @brief Get number of resource handles in resource list handle\r
+ * @param[in] list resource list handle\r
+ * @return number of resource handles in resource list handle\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_list_get_count(rm_resource_list_h list);\r
+\r
+/**\r
+ * @brief Get node of the resource\r
+ * @param[in] resource resource handle\r
+ * @return node of the resource\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+const char *rm_resource_get_node(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get id of the resource\r
+ * @param[in] resource resource handle\r
+ * @return resource id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_get_id(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get category id of the resource\r
+ * @param[in] resource resource handle\r
+ * @return resource id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_get_category(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get category id of the resource\r
+ * @param[in] resource resource handle\r
+ * @return resource id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_get_cur_category(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get consumer id using the resource\r
+ * @param[in] resource resource handle\r
+ * @return resource id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_get_consumer(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get state of the resource\r
+ * @param[in] resource resource handle\r
+ * @return resource id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+int rm_resource_get_state(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get application id using the resource\r
+ * @param[in] resource resource handle\r
+ * @return resource id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+const char *rm_resource_get_app_id(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Check whether the resource is being used by the android app\r
+ * @param[in] resource resource handle\r
+ * @return true : the resource is being used by the android app, false : not being used by the android app\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ */\r
+bool rm_resource_android_app(const rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get framerate of the resource\r
+ * @param[in] resource resource handle\r
+ * @return framerate\r
+ * @pre None\r
+ * @post None\r
+ * @version 3.0\r
+ * @exception None\r
+ */\r
+unsigned int rm_resource_get_framerate(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get max resolution of the resource\r
+ * @param[in] resource resource handle\r
+ * @return max resolution. This is one of rm_resolution_e values.\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li The API is valid for the resource belongs to RM_CATEGORY_DISPLAY_OUT\r
+ */\r
+int rm_resource_get_max_resolution(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief This function returns whether the resource supports overlay or not\r
+ * @param[in] resource resource handle\r
+ * @return true : overlay supported, false : overlay not supported\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @version 3.0\r
+ * @remark\r
+ * \li The API is valid for the resource belongs to RM_CATEGORY_DISPLAY_OUT\r
+ */\r
+bool rm_resource_support_overlay(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get max sampling format of the resource\r
+ * @param[in] resource resource handle\r
+ * @return max color format. This is one of rm_sampling_format_e values.\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li The API is valid for the resource belongs to RM_CATEGORY_DISPLAY_OUT\r
+ */\r
+int rm_resource_get_max_sampling_format(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get multiview zone id of the resource\r
+ * @param[in] resource resource handle\r
+ * @return multiview zone id\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li The API is valid for the resource belongs to RM_CATEGORY_SCALER\r
+ */\r
+int rm_resource_get_zone_id(rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get width of the resource\r
+ * @param[in] resource resource handle\r
+ * @return width of the content to be encoded\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li The API is valid for the resource belongs to RM_CATEGORY_VIDEO_ENCODER\r
+ */\r
+unsigned int rm_resource_get_width(const rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Get height of the resource\r
+ * @param[in] resource resource handle\r
+ * @return height of the content to be encoded\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li The API is valid for the resource belongs to RM_CATEGORY_VIDEO_ENCODER\r
+ */\r
+unsigned int rm_resource_get_height(const rm_resource_h resource);\r
+\r
+/**\r
+ * @brief Create a video encoder handle\r
+ * @param[in] width width of the content to encode (in pixel)\r
+ * @param[in] height height of the content to encode (in pixel)\r
+ * @param[in] framerate frame rate of the content to encode (frame per second)\r
+ * @return resource handle on success, otherwise NULL\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li If the returned resource handle is appended to the resource list then you can free this with rm_free_resource_list()\r
+ */\r
+rm_resource_h rm_create_video_encoder(const unsigned int width, const unsigned int height, const unsigned int framerate);\r
+\r
+/**\r
+ * @brief Checks whether the video encoders in the list are allocatable for multi encoding scenario\r
+ * @param[in] list the resource list including the video encoders\r
+ * @param[out] result true : allocatable, false : not allocatable\r
+ * @return RM_OK on success, otherwise RM_ERROR\r
+ * @pre None\r
+ * @post None\r
+ * @exception None\r
+ * @remark\r
+ * \li This function checks whether the video encoders are allocatable based on available bandwidth of the video encoder.\r
+ * \li In other words, the result can be different depending on current video encoder usage status.\r
+ */\r
+int rm_allocatable_video_encoders(const rm_resource_list_h list, bool *result);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif //__RM_RESOURCE_H__\r
diff --git a/include/rm_shm_api.h b/include/rm_shm_api.h
new file mode 100644 (file)
index 0000000..7e285d3
--- /dev/null
@@ -0,0 +1,117 @@
+/*
+ * 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 __RM_SHM_API_H__
+#define __RM_SHM_API_H__
+#include <rm_type.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @vd_noapi
+ * @brief Get application id of handle from shared memory
+ * @param[in] handle player handle returned by rm_register()
+ * @param[out] app_id application id of handle
+ * @return RM_OK on success, otherwise RM_ERROR
+ * @pre None
+ * @post None
+ * @exception None
+ * @remark
+ * \li This API is supposed to be called by the resource center only
+ * \li Do not use for other purpose
+ */
+int rm_shm_get_app_id(const int handle, char** app_id);
+
+/**
+ * @vd_noapi
+ * @brief Find hardware id of scaler allocated to a multiview zone
+ * @param[in] zone_id multiview zone id
+ * @param[out] hw_id hardware id of scaler
+ * @return RM_OK on success, otherwise RM_ERROR
+ * @pre None
+ * @post None
+ * @exception None
+ * @remark
+ * \li This API is supposed to be called by the resource center only
+ * \li Do not use for other purpose
+ */
+int rm_shm_find_scaler_hw_id(const int zone_id, int *hw_id);
+
+/**
+ * @vd_noapi
+ * @brief Find device id of scaler
+ * @param[in] virtual_id scaler virtual id
+ * @param[out] device_id scaler device id
+ * @return RM_OK on success, otherwise RM_ERROR
+ * @pre None
+ * @post None
+ * @exception None
+ * @remark
+ * \li This API is supposed to be called by the resource center only
+ * \li Do not use for other purpose
+ */
+int rm_shm_find_device_id(const int virtual_id, int *device_id);
+
+/**
+ * @vd_noapi
+ * @brief Find player list using main audio out
+ * @param[in] list player list
+ * @return RM_OK on success, otherwise RM_ERROR
+ * @pre None
+ * @post None
+ * @exception None
+ * @remark
+ * \li This API is supposed to be called by the resource center only
+ * \li Do not use for other purpose
+ */
+int rm_shm_find_players_using_audio_main_out(rm_resource_list_h *list);
+
+/**
+ * @vd_noapi
+ * @brief Get audio out being used by handle
+ * @param[in] handle player id
+ * @param[out] audio_out audio outs being used by handle
+ * @return RM_OK on success, otherwise RM_ERROR
+ * @pre None
+ * @post None
+ * @exception None
+ * @remark
+ * \li This API is supposed to be called by the resource center only
+ * \li Do not use for other purpose
+ */
+int rm_shm_get_active_audio_out(const int handle, int *audio_out);
+
+/**
+ * @vd_noapi
+ * @brief Check if the player handle is registered or not
+ * @param[in] handle player id
+ * @param[out] result true : player handle is registered, false : player handle is not registered
+ * @return RM_OK on success, otherwise RM_ERROR
+ * @pre None
+ * @post None
+ * @exception None
+ * @remark
+ * \li This API is supposed to be called by the resource center only
+ * \li Do not use for other purpose
+ */
+int rm_shm_active_player(const int handle, bool *result);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
\ No newline at end of file
diff --git a/include/rm_type.h b/include/rm_type.h
new file mode 100644 (file)
index 0000000..277fcc4
--- /dev/null
@@ -0,0 +1,653 @@
+/*
+ * 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 __RM_TYPE_H__
+#define __RM_TYPE_H__
+
+#include <resource-information/ri-common-type.h>
+
+#define IN
+#define OUT
+
+/**
+ * @brief      The callback execution result
+ */
+typedef enum {
+       RM_CB_RESULT_OK, /**< callback event has been processed successfully */
+       RM_CB_RESULT_ERROR /**< callback event has been processed with error */
+} rm_cb_result;
+
+
+/**
+ * @brief The resource category to which device belongs
+ * @version 4.0
+ */
+typedef enum {
+       RM_CATEGORY_VIDEO_ENCODER_NOT_SUPPORTED = RI_CATEGORY_VIDEO_ENCODER_NOT_SUPPORTED, /**< Not supported video encoder, support since 5.0 */
+       RM_CATEGORY_IMAGE_DECODER_NOT_SUPPORTED = RI_CATEGORY_IMAGE_DECODER_NOT_SUPPORTED, /**< Not supported Image decoder */
+       RM_CATEGORY_NOT_PERMITTED = RI_CATEGORY_NOT_PERMITTED, /**< Not permitted category by resource policy */
+       RM_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED = RI_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED,
+       RM_CATEGORY_JPEG_DECODER_NOT_SUPPORTED = RI_CATEGORY_JPEG_DECODER_NOT_SUPPORTED,
+       RM_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED = RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED,
+       RM_CATEGORY_NONE = RI_CATEGORY_NONE, /**< no category information */
+       RM_CATEGORY_AUDIO_DECODER = RI_CATEGORY_AUDIO_DECODER,     /**< Audio Decoder */
+       RM_CATEGORY_AUDIO_EVENT_COMPRESS = RI_CATEGORY_AUDIO_EVENT_COMPRESS,
+       RM_CATEGORY_AUDIO_SPDIF_ES_OUTPUT = RI_CATEGORY_AUDIO_SPDIF_ES_OUTPUT, /**< spdif es output */
+       RM_CATEGORY_VIDEO_DECODER = RI_CATEGORY_VIDEO_DECODER,     /**< Video Decoder - MFD (Multi Format Decoder), FullHD */
+       RM_CATEGORY_DEMUX = RI_CATEGORY_DEMUX,                     /**< Demux */
+       RM_CATEGORY_AUDIO_ENCODER = RI_CATEGORY_AUDIO_ENCODER,     /**< Audio Encoder */
+       RM_CATEGORY_VIDEO_ENCODER = RI_CATEGORY_VIDEO_ENCODER,     /**< Video Encoder */
+       RM_CATEGORY_SCALER = RI_CATEGORY_SCALER,                   /**< Main Scaler */
+       RM_CATEGORY_TUNER = RI_CATEGORY_TUNER,                     /**< Tuner */
+       RM_CATEGORY_AUDIO_MAIN_OUT = RI_CATEGORY_AUDIO_MAIN_OUT,   /**< Logical resource to manage ALSA main out source */
+       RM_CATEGORY_AUDIO_REMOTE_OUT = RI_CATEGORY_AUDIO_REMOTE_OUT, /**< Logical resource to manage ALSA remote out source */
+       RM_CATEGORY_AUDIO_SCART_OUT = RI_CATEGORY_AUDIO_SCART_OUT,   /**< Logical resource to manage ALSA scart out source */
+       RM_CATEGORY_MM_PCM_OUT = RI_CATEGORY_MM_PCM_OUT,           /**< PCM out - used by mm-player */
+       RM_CATEGORY_AUDIO_DECODER_SUB = RI_CATEGORY_AUDIO_DECODER_SUB, /**< Sub Audio Decoder */
+       RM_CATEGORY_AUDIO_DECODER_PRIMARY = RI_CATEGORY_AUDIO_DECODER_PRIMARY, /**< Sub Audio Decoder */
+       RM_CATEGORY_JPEG_DECODER = RI_CATEGORY_JPEG_DECODER,       /**< JPEG Decoder */
+       RM_CATEGORY_SCALER_SUB = RI_CATEGORY_SCALER_SUB,           /**< Sub Scaler */
+       RM_CATEGORY_EXT_VIDEO_SRC = RI_CATEGORY_EXT_VIDEO_SRC,     /**< Logical resource to manage video input path - used by player */
+       RM_CATEGORY_EXT_AUDIO_SRC = RI_CATEGORY_EXT_AUDIO_SRC,     /**< Logical resource to manage audio input path - used by player */
+       RM_CATEGORY_EXT_HDMI_SRC = RI_CATEGORY_EXT_HDMI_SRC,       /**< Logical resource to manage hdmi input path - used by player */
+       RM_CATEGORY_VIDEO_DECODER_SUB = RI_CATEGORY_VIDEO_DECODER_SUB, /**< Sub Video Decoder - MFD (Multi Format Decoder), FullHD */
+       RM_CATEGORY_CAMERA = RI_CATEGORY_CAMERA,                   /**< Logical resource to manage camera device */
+       RM_CATEGORY_DEMUX_REC = RI_CATEGORY_DEMUX_REC,             /**< Demux for recording */
+       RM_CATEGORY_TUNER_SUB = RI_CATEGORY_TUNER_SUB,             /**< Sub Tuner */
+       RM_CATEGORY_MJPEG_DECODER = RI_CATEGORY_MJPEG_DECODER,     /**< MJPEG decoder */
+
+       RM_CATEGORY_INPUT_SRC_DTV = RI_CATEGORY_INPUT_SRC_DTV,     /**< input source dtv */
+       RM_CATEGORY_INPUT_SRC_ATV = RI_CATEGORY_INPUT_SRC_ATV,     /**< input source atv */
+       RM_CATEGORY_INPUT_SRC_HDMI = RI_CATEGORY_INPUT_SRC_HDMI,   /**< input source hdmi */
+       RM_CATEGORY_INPUT_SRC_COMP = RI_CATEGORY_INPUT_SRC_COMP,   /**< input source comp */
+       RM_CATEGORY_INPUT_SRC_AV = RI_CATEGORY_INPUT_SRC_AV,       /**< input source av */
+       RM_CATEGORY_INPUT_SRC_SCART = RI_CATEGORY_INPUT_SRC_SCART, /**< input source scart */
+
+       RM_CATEGORY_MIC = RI_CATEGORY_MIC,                   /**< MIC */
+       RM_CATEGORY_EXT_COMP_SRC = RI_CATEGORY_EXT_COMP_SRC, /**< ext comp src */
+       RM_CATEGORY_EXT_AV_SRC = RI_CATEGORY_EXT_AV_SRC,     /**< ext av src */
+       RM_CATEGORY_SW_DECODER = RI_CATEGORY_SW_DECODER,     /**< sw decoder */
+       RM_CATEGORY_MMP_MEMORY_CLUSTER = RI_CATEGORY_MMP_MEMORY_CLUSTER, /**< mem cluster */
+
+       RM_CATEGORY_EXT_AUDIO_SRC_DVI = RI_CATEGORY_EXT_AUDIO_SRC_DVI,   /**< LFD only */
+       RM_CATEGORY_EXT_AUDIO_SRC_HDMI = RI_CATEGORY_EXT_AUDIO_SRC_HDMI, /**< LFD only */
+       RM_CATEGORY_EXT_AUDIO_SRC_DP = RI_CATEGORY_EXT_AUDIO_SRC_DP,   /**<LFD only, Diplay Port */
+       RM_CATEGORY_EXT_AUDIO_SRC_SBB = RI_CATEGORY_EXT_AUDIO_SRC_SBB, /**<LFD only, MagicInfo I */
+       RM_CATEGORY_EXT_AUDIO_SRC_OPS = RI_CATEGORY_EXT_AUDIO_SRC_OPS, /**<LFD only, PIM(Plug In Module) */
+
+       RM_CATEGORY_EXT_VIDEO_SRC_DVI = RI_CATEGORY_EXT_VIDEO_SRC_DVI,  /**<LFD only */
+       RM_CATEGORY_EXT_VIDEO_SRC_HDMI = RI_CATEGORY_EXT_VIDEO_SRC_HDMI,/**<LFD only */
+       RM_CATEGORY_EXT_VIDEO_SRC_DP = RI_CATEGORY_EXT_VIDEO_SRC_DP,   /**<LFD only, Diplay Port */
+       RM_CATEGORY_EXT_VIDEO_SRC_SBB = RI_CATEGORY_EXT_VIDEO_SRC_SBB, /**<LFD only, MagicInfo I */
+       RM_CATEGORY_EXT_VIDEO_SRC_OPS = RI_CATEGORY_EXT_VIDEO_SRC_OPS, /**<LFD only, PIM(Plug In Module) */
+       RM_CATEGORY_EXT_PC_SRC = RI_CATEGORY_EXT_PC_SRC,
+
+       RM_CATEGORY_SCALER_BG = RI_CATEGORY_SCALER_BG,
+       RM_CATEGORY_AUDIO_SUB_OUT = RI_CATEGORY_AUDIO_SUB_OUT,  /**< Logical resource to manage ALSA sub out source */
+       RM_CATEGORY_GRAPHIC_PLANE = RI_CATEGORY_GRAPHIC_PLANE,  /**< Logical resource to manage Graphic plane */
+       RM_CATEGORY_DISPLAY_OUT = RI_CATEGORY_DISPLAY_OUT,      /**< Logical resource to manage Display output */
+       RM_CATEGORY_IMAGE_DECODER = RI_CATEGORY_IMAGE_DECODER,  /**< Image decoder */
+       RM_CATEGORY_VIDEO_ENCODER_EXCLUSIVE = RI_CATEGORY_VIDEO_ENCODER_EXCLUSIVE, /**< Video encoder - dedicated to duo scenario */
+       RM_CATEGORY_AUDIO_MAIN_OUT_SHARE = RI_CATEGORY_AUDIO_MAIN_OUT_SHARE, /**< Logical resource to manage ALSA main out source - sharable - support since 4.0 */
+       RM_CATEGORY_VIDEO_ENCODER_MULTI = RI_CATEGORY_VIDEO_ENCODER_MULTI,  /**< Video encoder for multi encoding - support since 5.0 */
+
+       RM_CATEGORY_JPEG_DECODER_OPTION = RI_CATEGORY_JPEG_DECODER_OPTION, /**< JPEG Decoder option max*/
+       RM_CATEGORY_JPEG_DECODER_FHD = RI_CATEGORY_JPEG_DECODER_FHD, /**< FHD JPEG Decoder */
+       RM_CATEGORY_JPEG_DECODER_UHD = RI_CATEGORY_JPEG_DECODER_UHD, /**< UHD JPEG Decoder */
+       RM_CATEGORY_JPEG_DECODER_8K = RI_CATEGORY_JPEG_DECODER_8K,   /**< 8K JPEG Decoder */
+
+       RM_CATEGORY_MJPEG_DECODER_OPTION = RI_CATEGORY_MJPEG_DECODER_OPTION, /**< MJPEG Decoder option min*/
+       RM_CATEGORY_MJPEG_DECODER_FHD = RI_CATEGORY_MJPEG_DECODER_FHD, /**< FHD MJPEG Decoder */
+       RM_CATEGORY_MJPEG_DECODER_UHD = RI_CATEGORY_MJPEG_DECODER_UHD, /**< UHD MJPEG Decoder */
+       RM_CATEGORY_MJPEG_DECODER_8K = RI_CATEGORY_MJPEG_DECODER_8K,   /**< 8K MJPEG Decoder */
+
+       RM_CATEGORY_HEIC_DECODER_OPTION = RI_CATEGORY_HEIC_DECODER_OPTION, /**< HEIC Decoder option min */
+       RM_CATEGORY_HEIC_DECODER = RI_CATEGORY_HEIC_DECODER,               /**< HEIC Decoder */
+
+       RM_CATEGORY_AUDIO_DECODER_OPTION = RI_CATEGORY_AUDIO_DECODER_OPTION, /**< Audio Decoder option min*/
+       RM_CATEGORY_AUDIO_DECODER_ANY = RI_CATEGORY_AUDIO_DECODER_ANY,       /**< Available audio Decoder will be allocated*/
+       RM_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED = RI_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED, /**< Audio Decoder is not supported*/
+       RM_CATEGORY_AUDIO_DECODER_MPEG = RI_CATEGORY_AUDIO_DECODER_MPEG,     /**< audio decoder for mpeg */
+       RM_CATEGORY_AUDIO_DECODER_AC3 = RI_CATEGORY_AUDIO_DECODER_AC3,       /**< audio decoder for AC3 */
+       RM_CATEGORY_AUDIO_DECODER_E_AC3 = RI_CATEGORY_AUDIO_DECODER_E_AC3,   /**< audio decoder for E-AC3 */
+       RM_CATEGORY_AUDIO_DECODER_TRUEHD = RI_CATEGORY_AUDIO_DECODER_TRUEHD, /**< audio decoder for TrueHD */
+       RM_CATEGORY_AUDIO_DECODER_AC4 = RI_CATEGORY_AUDIO_DECODER_AC4,       /**< audio decoder for AC4 */
+       RM_CATEGORY_AUDIO_DECODER_VORBIS = RI_CATEGORY_AUDIO_DECODER_VORBIS, /**< audio decoder for Vorbis */
+       RM_CATEGORY_AUDIO_DECODER_G2COOK = RI_CATEGORY_AUDIO_DECODER_G2COOK, /**< audio decoder for G2Cook */
+       RM_CATEGORY_AUDIO_DECODER_AAC = RI_CATEGORY_AUDIO_DECODER_AAC,       /**< audio decoder for AAC */
+       RM_CATEGORY_AUDIO_DECODER_HE_AAC = RI_CATEGORY_AUDIO_DECODER_HE_AAC, /**< audio decoder for HE-AAC */
+       RM_CATEGORY_AUDIO_DECODER_WMA = RI_CATEGORY_AUDIO_DECODER_WMA,       /**< audio decoder for WMA */
+       RM_CATEGORY_AUDIO_DECODER_ADPCM = RI_CATEGORY_AUDIO_DECODER_ADPCM,   /**< audio decoder for ADPCM */
+       RM_CATEGORY_AUDIO_DECODER_MPEG_H = RI_CATEGORY_AUDIO_DECODER_MPEG_H, /**< audio decoder for MPEG-H */
+       RM_CATEGORY_AUDIO_DECODER_OPUS = RI_CATEGORY_AUDIO_DECODER_OPUS,     /**< audio decoder for OPUS */
+       RM_CATEGORY_AUDIO_DECODER_PCM = RI_CATEGORY_AUDIO_DECODER_PCM,       /**< audio decoder for PCM */
+       RM_CATEGORY_AUDIO_DECODER_IAMF_OPUS = RI_CATEGORY_AUDIO_DECODER_IAMF_OPUS, /**< audio decoder for IAMF OPUS */
+       RM_CATEGORY_AUDIO_OFFLOAD = RI_CATEGORY_AUDIO_OFFLOAD,                     /**< audio offload */
+
+       RM_CATEGORY_RADIO = RI_CATEGORY_RADIO,                 /**< radio */
+
+       RM_CATEGORY_SCALER_OPTION = RI_CATEGORY_SCALER_OPTION, /**< Video scaler option */
+       RM_CATEGORY_SCALER_MULTIVIEW = RI_CATEGORY_SCALER_MULTIVIEW, /**< Video scaler for multiview */
+       RM_CATEGORY_SCALER_SUB2 = RI_CATEGORY_SCALER_SUB2, /**< 902: Video scaler sub2 */
+       RM_CATEGORY_SCALER_SUB3 = RI_CATEGORY_SCALER_SUB3, /**< 903: Video scaler sub3 */
+       RM_CATEGORY_SCALER_VR360_DETILED = RI_CATEGORY_SCALER_VR360_DETILED, /**< 904: Video scaler for VR360 detailed */
+       RM_CATEGORY_SCALER_VR360_NATIVE_OUT = RI_CATEGORY_SCALER_VR360_NATIVE_OUT, /**< 905: Video scaler for VR360 native out */
+       RM_CATEGORY_SCALER_INTERLACED = RI_CATEGORY_SCALER_INTERLACED, /**< 906: Video scaler for interlaced stream */
+       RM_CATEGORY_SCALER_8K = RI_CATEGORY_SCALER_8K, /**< 907: Scaler for 8K output */
+       RM_CATEGORY_SCALER_PROGRESSIVE = RI_CATEGORY_SCALER_PROGRESSIVE, /**< 908: Video scaler for progressive stream */
+       RM_CATEGORY_SCALER_HDMI = RI_CATEGORY_SCALER_HDMI, /**< 909: Video scaler for HDMI input, support since version 4.0 */
+       RM_CATEGORY_SCALER_HDMI_SUB = RI_CATEGORY_SCALER_HDMI_SUB, /**< 910: Video scaler sub for HDMI input, support since version 4.0 */
+       RM_CATEGORY_SCALER_HDMI_MV = RI_CATEGORY_SCALER_HDMI_MV, /**< 911: Video scaler for HDMI input multiview, support since version 4.0 */
+       RM_CATEGORY_SCALER_MINIMAP = RI_CATEGORY_SCALER_MINIMAP, /**< 912: Video scaler for Minimap, support since version 5.0 */
+       RM_CATEGORY_SCALER_MULTI_HDMI = RI_CATEGORY_SCALER_MULTI_HDMI, /**< 913: Video scaler for Multi-HDMI input, support since version 5.3 */
+       RM_CATEGORY_SCALER_INAPP_MULTIVIEW = RI_CATEGORY_SCALER_INAPP_MULTIVIEW, /**< 914: Video scaler for inapp Multiview , support since version 5.4 */
+       RM_CATEGORY_SCALER_GSR = RI_CATEGORY_SCALER_GSR, /**< 915: Video scaler for gsr feature , support since version 6.0 */
+
+       RM_CATEGORY_VIDEO_DECODER_OPTION = RI_CATEGORY_VIDEO_DECODER_OPTION,  /**< Video Decoder option min*/
+       RM_CATEGORY_VIDEO_DECODER_UHD = RI_CATEGORY_VIDEO_DECODER_UHD, /**< Video Decoder, UHD */
+       RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P, /**< video decoder for mjpeg */
+       RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_60P, /**< video decoder for mjpeg */
+       RM_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P, /**< video decoder for mjpeg */
+       RM_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_60P, /**< video decoder for mjpeg */
+       RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, /**< video decoder for mjpeg */
+       RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P, /**< video decoder for mjpeg */
+       RM_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_30P, /**< video decoder for h263 */
+       RM_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_60P, /**< video decoder for h263 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P, /**< video decoder for h264 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P, /**< video decoder for h264 */
+       RM_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_30P, /**< video decoder for h264 */
+       RM_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_60P, /**< video decoder for h264 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_30P, /**< video decoder for vp8 */
+       RM_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_60P, /**< video decoder for vp8 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_30P, /**< video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_60P, /**< video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_30P, /**< video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_60P, /**< video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_30P, /**< video decoder for rv */
+       RM_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_60P, /**< video decoder for rv */
+       RM_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_30P, /**< video decoder for wmv9 */
+       RM_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_60P, /**< video decoder for wmv9 */
+       RM_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_30P, /**< video decoder for avs */
+       RM_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_60P, /**< video decoder for avs */
+       RM_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_30P, /**< video decoder for avs+ */
+       RM_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_60P, /**< video decoder for avs+ */
+
+       //VR360
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_8BIT_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_8BIT_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_420_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_420_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_FHD_10BIT_422_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_30P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_VR360_UHD_10BIT_422_60P, /**< video decoder for hevc vr360 */
+       RM_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_30P, /**< video decoder for h264 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_FHD_8BIT_60P, /**< video decoder for h264 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_30P, /**< video decoder for h264 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_VR360_UHD_8BIT_60P, /**< video decoder for h264 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_30P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_8BIT_60P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_30P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_8BIT_60P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_30P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_60P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_30P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_60P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_30P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_FHD_10BIT_420_60P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_30P, /**< video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_VP9_VR360_UHD_10BIT_420_60P, /**< video decoder for vp9 vr360 */
+
+       RM_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_8BIT_60P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_30P, /**< video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_SHVC_10BIT_60P, /**< video decoder for hevc */
+
+
+       RM_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_30P, /**< 1080: video decoder for hevc 8k */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_8BIT_60P, /**< 1081: video decoder for hevc 8k */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_30P, /**< 1082: video decoder for hevc 8k */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_60P, /**< 1083: video decoder for hevc 8k */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_30P, /**< 1084: video decoder for hevc 8k */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_8K_10BIT_420_60P, /**< 1085: video decoder for hevc 8k */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_120P,          /**< 1086: video decoder for hevc, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_120P,         /**< 1087: video decoder for hevc, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_120P,     /**< 1088: video decoder for hevc, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_422_120P,     /**< 1089: video decoder for hevc, support since version 4.0 */
+
+       RM_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_30P,      /**< 1090: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_60P,      /**< 1091: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P,    /**< 1092: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P,    /**< 1093: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_30P,      /**< 1094: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_60P,      /**< 1095: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P,    /**< 1096: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P,    /**< 1097: video decoder for av1 */
+
+       RM_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_30P,                /**< 1098: video decoder for av1 8k */
+       RM_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_60P,                /**< 1099: video decoder for av1 8k */
+       RM_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P,              /**< 1100: video decoder for av1 8k */
+       RM_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P,              /**< 1101: video decoder for av1 8k */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_30P,  /**< 1102: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_60P,  /**< 1103: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_30P,/**< 1104: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_60P,/**< 1105: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_30P,  /**< 1106: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_60P,  /**< 1107: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_30P,/**< 1108: video decoder for vp9 vr360 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_60P,/**< 1109: video decoder for vp9 vr360 */
+
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_120P,           /**< 1110: video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_120P,         /**< 1111: video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_120P = RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_422_120P, /**< 1112: video decoder for hevc */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_120P,           /**< 1113: video decoder for h264 */
+       RM_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_HD_8BIT_30P,                /**< 1114: video decoder for h264 */
+
+       RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_120P,         /**< 1115: video decoder for mpeg1 */
+       RM_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_120P,         /**< 1116: video decoder for mpeg2 */
+       RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_120P,         /**< 1117: video decoder for mpeg4 */
+       RM_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_120P,           /**< 1118: video decoder for h263 */
+       RM_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_120P,             /**< 1119: video decoder for vp8 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_120P,             /**< 1120: video decoder for vp8 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_120P,           /**< 1121: video decoder for vp8 */
+       RM_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_120P,               /**< 1122: video decoder for rv */
+       RM_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_120P,           /**< 1123: video decoder for wmv9 */
+       RM_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_120P,             /**< 1124: video decoder for avs */
+       RM_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_120P,   /**< 1125: video decoder for avs+ */
+       RM_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_120P,             /**< 1126: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_120P,           /**< 1127: video decoder for av1 */
+
+       RM_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_30P,             /**< 1128: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_60P,             /**< 1129: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_8BIT_120P,           /**< 1130: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_30P,           /**< 1131: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_60P,           /**< 1132: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS2_FHD_10BIT_120P,         /**< 1133: video decoder for avs2 */
+
+       RM_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_30P,             /**< 1134: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_8BIT_60P,             /**< 1135: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_30P,           /**< 1136: video decoder for avs2 */
+       RM_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS2_UHD_10BIT_60P,           /**< 1137: video decoder for avs2 */
+
+       RM_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_30P,             /**< 1138: video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_60P,             /**< 1139: video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_30P,             /**< 1140: video decoder for vp9 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_60P,             /**< 1141: video decoder for vp9 */
+
+       RM_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_120P,             /**< 1142: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P,           /**< 1143: video decoder for av1 */
+       RM_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP8_qHD_8BIT_30P,               /**< 1144: video decoder for vp8 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_FHD_N_8BIT_30P,         /**< 1145: video decoder for h264 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_MV = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_MV,       /**< 1146: video decoder for h264 multiview scenario */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_MV = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_MV,       /**< 1147: video decoder for h264 multiview scenario */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_PORTRAIT = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_PORTRAIT,  /**< 1148: video decoder for h264 portrait */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PORTRAIT = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PORTRAIT,  /**< 1149: video decoder for h264 portrait */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_INTERLACED = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_INTERLACED, /**< 1150: video decoder for h264 interlaced */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_INTERLACED = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_INTERLACED, /**< 1151: video decoder for h264 interlaced */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_PROGRESSIVE = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_PROGRESSIVE, /**< 1152: video decoder dedicated to h264 progressive, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PROGRESSIVE = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_PROGRESSIVE, /**< 1153: video decoder dedicated to h264 progressive, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_H264_QuadHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_H264_QuadHD_8BIT_30P,       /**< 1154: video decoder for h264, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_H264_QuadHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_H264_QuadHD_8BIT_60P,       /**< 1155: video decoder for h264, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_DQHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_DQHD_8BIT_30P,           /**< 1156: video decoder for HEVC, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_DQHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_DQHD_8BIT_60P,           /**< 1157: video decoder for HEVC, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_DQHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_DQHD_10BIT_30P,         /**< 1158: video decoder for HEVC, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_DQHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_DQHD_10BIT_60P,         /**< 1159: video decoder for HEVC, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_DQHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_DQHD_8BIT_30P,             /**< 1160: video decoder for AV1, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_DQHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_DQHD_8BIT_60P,             /**< 1161: video decoder for AV1, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_DQHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_DQHD_10BIT_30P,           /**< 1162: video decoder for AV1, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_DQHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_DQHD_10BIT_60P,           /**< 1163: video decoder for AV1, support since version 4.0 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_5K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_5K_8BIT_30P,               /**< 1164: video decoder for HEVC, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_5K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_5K_8BIT_60P,               /**< 1165: video decoder for HEVC, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_5K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_HEVC_5K_10BIT_30P,             /**< 1166: video decoder for HEVC, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_HEVC_5K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_HEVC_5K_10BIT_60P,             /**< 1167: video decoder for HEVC, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_5K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_5K_8BIT_30P,                 /**< 1168: video decoder for AV1, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_5K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_5K_8BIT_60P,                 /**< 1169: video decoder for AV1, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_5K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AV1_5K_10BIT_30P,               /**< 1170: video decoder for AV1, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_AV1_5K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AV1_5K_10BIT_60P,               /**< 1171: video decoder for AV1, support since version 5.3 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_TRIPLE = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_TRIPLE, /**< 1172: video decoder for h264 triple, support since version 5.4 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VVC_FHD_8BIT_30P,              /**< 1173: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VVC_FHD_8BIT_60P,              /**< 1174: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_VVC_FHD_8BIT_120P,            /**< 1175: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VVC_FHD_10BIT_30P,            /**< 1176: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VVC_FHD_10BIT_60P,            /**< 1177: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_VVC_FHD_10BIT_120P,          /**< 1178: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VVC_UHD_8BIT_30P,              /**< 1179: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VVC_UHD_8BIT_60P,              /**< 1180: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_UHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_VVC_UHD_8BIT_120P,            /**< 1181: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VVC_UHD_10BIT_30P,            /**< 1182: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VVC_UHD_10BIT_60P,            /**< 1183: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_UHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_VVC_UHD_10BIT_120P,          /**< 1184: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VVC_8K_8BIT_30P,                /**< 1185: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VVC_8K_8BIT_60P,                /**< 1186: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VVC_8K_10BIT_30P,              /**< 1187: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VVC_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VVC_8K_10BIT_60P,              /**< 1188: video decoder for VVC(H.266), support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_8K_8BIT_30P,                /**< 1189: video decoder for VP9, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_8K_8BIT_60P,                /**< 1190: video decoder for VP9, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_VP9_8K_10BIT_30P,              /**< 1191: video decoder for VP9, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_VP9_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_VP9_8K_10BIT_60P,              /**< 1192: video decoder for VP9, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_FHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS3_FHD_8BIT_30P,            /**< 1193: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_FHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS3_FHD_8BIT_60P,            /**< 1194: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_FHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS3_FHD_8BIT_120P,          /**< 1195: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_FHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS3_FHD_10BIT_30P,          /**< 1196: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_FHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS3_FHD_10BIT_60P,          /**< 1197: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_FHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS3_FHD_10BIT_120P,        /**< 1198: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_UHD_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS3_UHD_8BIT_30P,            /**< 1199: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_UHD_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS3_UHD_8BIT_60P,            /**< 1200: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_UHD_8BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS3_UHD_8BIT_120P,          /**< 1201: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_UHD_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS3_UHD_10BIT_30P,          /**< 1202: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_UHD_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS3_UHD_10BIT_60P,          /**< 1203: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_UHD_10BIT_120P = RI_CATEGORY_VIDEO_DECODER_AVS3_UHD_10BIT_120P,        /**< 1204: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_8K_8BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS3_8K_8BIT_30P,              /**< 1205: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_8K_8BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS3_8K_8BIT_60P,              /**< 1206: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_8K_10BIT_30P = RI_CATEGORY_VIDEO_DECODER_AVS3_8K_10BIT_30P,            /**< 1207: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_AVS3_8K_10BIT_60P = RI_CATEGORY_VIDEO_DECODER_AVS3_8K_10BIT_60P,             /**< 1208: video decoder for AVS3, support since version 6.0 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_DETILED = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P_DETILED, /**< 1209: video decoder for h264 detiled, support since version 6.4 */
+       RM_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_DETILED = RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P_DETILED, /**< 1210: video decoder for h264 detiled, support since version 6.4 */
+} rm_rsc_category_e;
+
+/**
+ * @brief The device id
+ * @version 3.0
+ */
+typedef enum
+{
+       RM_DEVICE_NONE = RI_DEVICE_UNDEFINED,                                 /**< undefined device */
+       RM_DEVICE_AUDIO_MAIN_OUT = RI_DEVICE_AUDIO_MAIN_OUT,                  /**< audio main out */
+       RM_DEVICE_AUDIO_EVENT_COMPRESS = RI_DEVICE_AUDIO_EVENT_COMPRESS,      /**< audio event compress */
+       RM_DEVICE_AUDIO_REMOTE_OUT = RI_DEVICE_AUDIO_REMOTE_OUT,              /**< audio remote out */
+       RM_DEVICE_AUDIO_SCART_OUT = RI_DEVICE_AUDIO_SCART_OUT,                /**< audio scart out */
+       RM_DEVICE_MM_PCM_OUT = RI_DEVICE_MM_PCM_OUT,                          /**< mm pcm out */
+       RM_DEVICE_JPEG_DECODER = RI_DEVICE_JPEG_DECODER,                      /**< jpeg decoder */
+       RM_DEVICE_DEMUX0 = RI_DEVICE_DEMUX0,                                  /**< demux instance 0 */
+       RM_DEVICE_DEMUX1 = RI_DEVICE_DEMUX1,                                  /**< demux instance 1 */
+       RM_DEVICE_DEMUX2 = RI_DEVICE_DEMUX2,                                  /**< demux instance 2 */
+       RM_DEVICE_DEMUX3 = RI_DEVICE_DEMUX3,                                  /**< demux instance 3 */
+       RM_DEVICE_AUDIO_ENCODER = RI_DEVICE_AUDIO_ENCODER,                    /**< audio encoder */
+       RM_DEVICE_VIDEO_ENCODER = RI_DEVICE_VIDEO_ENCODER,                    /**< video encoder */
+       RM_DEVICE_SCALER = RI_DEVICE_SCALER,                                  /**< video scaler (main) */
+       RM_DEVICE_EXT_VIDEO_SRC = RI_DEVICE_EXT_VIDEO_SRC,                    /**< external video source */
+       RM_DEVICE_EXT_AUDIO_SRC = RI_DEVICE_EXT_AUDIO_SRC,                    /**< external audio source */
+       RM_DEVICE_EXT_HDMI_SRC = RI_DEVICE_EXT_HDMI_SRC,                      /**< external HDMI source */
+       RM_DEVICE_CAMERA = RI_DEVICE_CAMERA,                                  /**< camera */
+       RM_DEVICE_TUNER = RI_DEVICE_TUNER,                                    /**< tuner */
+       RM_DEVICE_TUNER_SUB = RI_DEVICE_TUNER_SUB,                            /**< tuner (sub) */
+       RM_DEVICE_SCALER_SUB = RI_DEVICE_SCALER_SUB,                          /**< video scaler (sub) */
+       RM_DEVICE_AUDIO_DECODER = RI_DEVICE_AUDIO_DECODER,                    /**< audio decoder (main) */
+       RM_DEVICE_AUDIO_DECODER_SUB = RI_DEVICE_AUDIO_DECODER_SUB,            /**< audio decoder (sub) */
+       RM_DEVICE_AUDIO_DECODER_PRIMARY = RI_DEVICE_AUDIO_DECODER_PRIMARY,    /**< audio decoder (primary) */
+       RM_DEVICE_VIDEO_DECODER_MAIN = RI_DEVICE_VIDEO_DECODER_MAIN,          /**< video decoder (main) */
+       RM_DEVICE_VIDEO_DECODER_SUB = RI_DEVICE_VIDEO_DECODER_SUB,            /**< video decoder (sub) */
+       RM_DEVICE_VIDEO_DECODER_UDDEC = RI_DEVICE_VIDEO_DECODER_UDDEC,        /**< UDDEC video decoder */
+       RM_DEVICE_VIDEO_DECODER_UDHEVC = RI_DEVICE_VIDEO_DECODER_UDHEVC,      /**< UDHEVC video decoder */
+       RM_DEVICE_AUDIO_SPDIF_ES_OUTPUT = RI_DEVICE_AUDIO_SPDIF_ES_OUTPUT,    /**< SPDIF ES audio output */
+       RM_DEVICE_MIC = RI_DEVICE_MIC,                                        /**< mic */
+       RM_DEVICE_EXT_COMP_SRC = RI_DEVICE_EXT_COMP_SRC,                      /**< external composite source */
+       RM_DEVICE_EXT_AV_SRC = RI_DEVICE_EXT_AV_SRC,                          /**< external av source */
+       RM_DEVICE_MJPEG_DECODER = RI_DEVICE_MJPEG_DECODER,                    /**< mjpeg decoder */
+       RM_DEVICE_JPEG_DECODER_UHD = RI_DEVICE_JPEG_DECODER_UHD,              /**< jpeg decoder for UHD */
+       RM_DEVICE_MJPEG_DECODER_UHD = RI_DEVICE_MJPEG_DECODER_UHD,            /**< mjpeg decoder for UHD */
+       RM_DEVICE_SW_DECODER = RI_DEVICE_SW_DECODER,                          /**< software decoder */
+       RM_DEVICE_EXT_AUDIO_SRC_DVI = RI_DEVICE_EXT_AUDIO_SRC_DVI,            /**< external audio source DVI - LFD only */
+       RM_DEVICE_EXT_AUDIO_SRC_HDMI = RI_DEVICE_EXT_AUDIO_SRC_HDMI,          /**< external audio source HDMI - LFD only */
+       RM_DEVICE_EXT_AUDIO_SRC_DP = RI_DEVICE_EXT_AUDIO_SRC_DP,              /**< external audio source Display Port - LFD only */
+       RM_DEVICE_EXT_AUDIO_SRC_SBB = RI_DEVICE_EXT_AUDIO_SRC_SBB,            /**< external audio source Magic Info I - LFD only */
+       RM_DEVICE_EXT_AUDIO_SRC_OPS = RI_DEVICE_EXT_AUDIO_SRC_OPS,            /**< external audio source PIM(Plug In Module) - LFD only */
+       RM_DEVICE_EXT_VIDEO_SRC_DVI = RI_DEVICE_EXT_VIDEO_SRC_DVI,            /**< external video source DVI - LFD only */
+       RM_DEVICE_EXT_VIDEO_SRC_HDMI = RI_DEVICE_EXT_VIDEO_SRC_HDMI,          /**< external video source HDMI - LFD only */
+       RM_DEVICE_EXT_VIDEO_SRC_DP = RI_DEVICE_EXT_VIDEO_SRC_DP,              /**< external video source Diplay Port - LFD only */
+       RM_DEVICE_EXT_VIDEO_SRC_SBB = RI_DEVICE_EXT_VIDEO_SRC_SBB,            /**< external video source MagicInfo I - LFD only */
+       RM_DEVICE_EXT_VIDEO_SRC_OPS = RI_DEVICE_EXT_VIDEO_SRC_OPS,            /**< external video source PIM(Plug In Module) - LFD only */
+       RM_DEVICE_VIDEO_DECODER_DVDE0 = RI_DEVICE_VIDEO_DECODER_DVDE0,        /**< dvde0 video decoder */
+       RM_DEVICE_VIDEO_DECODER_DVDE1 = RI_DEVICE_VIDEO_DECODER_DVDE1,        /**< dvde1 video decoder */
+       RM_DEVICE_VIDEO_DECODER_HEN = RI_DEVICE_VIDEO_DECODER_HEN,            /**< hen video decoder */
+       RM_DEVICE_DEMUX4 = RI_DEVICE_DEMUX4,                                  /**< demux instance 4 */
+       RM_DEVICE_DEMUX5 = RI_DEVICE_DEMUX5,                                  /**< demux instance 5 */
+       RM_DEVICE_DEMUX6 = RI_DEVICE_DEMUX6,                                  /**< demux instance 6 */
+       RM_DEVICE_DEMUX7 = RI_DEVICE_DEMUX7,                                  /**< demux instance 7 */
+       RM_DEVICE_EXT_PC_SRC = RI_DEVICE_EXT_PC_SRC,                          /**< external source PC */
+       RM_DEVICE_VIDEO_DECODER_HEVC_8K = RI_DEVICE_VIDEO_DECODER_HEVC_8K,    /**< video decoder for HEVC 8K */
+       RM_DEVICE_VIDEO_DECODER_VR360DEC = RI_DEVICE_VIDEO_DECODER_VR360DEC,  /**< video decoder for VR360 */
+       RM_DEVICE_AUDIO_SUB_OUT = RI_DEVICE_AUDIO_SUB_OUT,                    /**< audio sub out */
+       RM_DEVICE_MJPEG_DECODER_SUB = RI_DEVICE_MJPEG_DECODER_SUB,            /**< mjpeg decoder (sub) */
+       RM_DEVICE_GRAPHIC_PLANE = RI_DEVICE_GRAPHIC_PLANE,                    /**< graphic plane */
+       RM_DEVICE_VIDEO_DECODER_DVDE2 = RI_DEVICE_VIDEO_DECODER_DVDE2,        /**< dvde2 video decoder */
+       RM_DEVICE_VIDEO_DECODER_DVDE3 = RI_DEVICE_VIDEO_DECODER_DVDE3,        /**< dvde3 video decoder */
+       RM_DEVICE_HEIC_DECODER = RI_DEVICE_HEIC_DECODER,                      /**< heic image decoder */
+       RM_DEVICE_VIDEO_DECODER_DVDE4 = RI_DEVICE_VIDEO_DECODER_DVDE4,        /**< dvde4 video decoder */
+       RM_DEVICE_VIDEO_DECODER_DVDE5 = RI_DEVICE_VIDEO_DECODER_DVDE5,        /**< dvde5 video decoder */
+       RM_DEVICE_VIDEO_DECODER_DVDE6 = RI_DEVICE_VIDEO_DECODER_DVDE6,        /**< dvde6 video decoder */
+       RM_DEVICE_VIDEO_DECODER_DVDE7 = RI_DEVICE_VIDEO_DECODER_DVDE7,        /**< dvde7 video decoder */
+       RM_DEVICE_VIDEO_DECODER_OVDE = RI_DEVICE_VIDEO_DECODER_OVDE,          /**< ovde0 video decoder */
+       RM_DEVICE_SCALER_SUB2 = RI_DEVICE_SCALER_SUB2,                        /**< video scaler (sub2) */
+       RM_DEVICE_SCALER_SUB3 = RI_DEVICE_SCALER_SUB3,                        /**< video scaler (sub3) */
+       RM_DEVICE_VIDEO_DECODER_MFC2 = RI_DEVICE_VIDEO_DECODER_MFC2,          /**< mfc2 video decoder */
+       RM_DEVICE_VIDEO_DECODER_MFC3 = RI_DEVICE_VIDEO_DECODER_MFC3,          /**< mfc3 video decoder */
+       RM_DEVICE_VIDEO_DECODER_MFC4 = RI_DEVICE_VIDEO_DECODER_MFC4,          /**< mfc4 video decoder */
+       RM_DEVICE_JPEG_DECODER_SUB = RI_DEVICE_JPEG_DECODER_SUB,              /**< jpeg decoder (sub) */
+       RM_DEVICE_VIDEO_ENCODER_EXCLUSIVE = RI_DEVICE_VIDEO_ENCODER_EXCLUSIVE,/**< video encoder (exclusive) */
+       RM_DEVICE_AUDIO_MAIN_OUT_SHARE0 = RI_DEVICE_AUDIO_MAIN_OUT_SHARE0,    /**< audio main out - sharable - support since 4.0 */
+       RM_DEVICE_AUDIO_MAIN_OUT_SHARE1 = RI_DEVICE_AUDIO_MAIN_OUT_SHARE1,    /**< audio main out - sharable - support since 4.0 */
+       RM_DEVICE_VIDEO_ENCODER_MULTI1 = RI_DEVICE_VIDEO_ENCODER_MULTI1,      /**< video encoder instance1 for multi encoding, support since version 5.0 */
+       RM_DEVICE_VIDEO_ENCODER_MULTI2 = RI_DEVICE_VIDEO_ENCODER_MULTI2,      /**< video encoder instance2 for multi encoding, support since version 5.0 */
+       RM_DEVICE_VIDEO_ENCODER_MULTI3 = RI_DEVICE_VIDEO_ENCODER_MULTI3,      /**< video encoder instance3 for multi encoding, support since version 5.0 */
+       RM_DEVICE_VIDEO_ENCODER_MULTI4 = RI_DEVICE_VIDEO_ENCODER_MULTI4,      /**< video encoder instance4 for multi encoding, support since version 5.0 */
+       RM_DEVICE_GSR = RI_DEVICE_GSR,                                        /**< video scaler for gsr feature, support since version 6.0 */
+       RM_DEVICE_AUDIO_OFFLOAD = RI_DEVICE_AUDIO_OFFLOAD,                    /**< audio offload */
+       RM_DEVICE_RADIO = RI_DEVICE_RADIO                                     /**< radio */
+} rm_device_e;
+
+
+/**
+ * @brief The device allocation option
+ */
+typedef enum {
+       RM_DEVICE_OPT_MAIN = (0x1 << 29),       /**< main device */
+       RM_DEVICE_OPT_SUB = (0x1 << 28),        /**< sub device */
+} rm_device_option_e;
+
+/**
+ * @brief        The requested resource state
+ */
+typedef enum {
+       RM_STATE_PASSIVE,               /**< passive state */
+       RM_STATE_SHARABLE,              /**< sharable state */
+       RM_STATE_EXCLUSIVE,             /**< exclusive state */
+       RM_STATE_EXCLUSIVE_CONDITIONAL, /**< conditional state */
+       RM_STATE_EXCLUSIVE_AUTO,        /**< auto state */
+       RM_STATE_EXCLUSIVE_PREFERENCE,  /**< exclusive preference state */
+} rm_requests_resource_state_e;
+
+/**
+ * @brief        The resource state
+ */
+typedef enum {
+       RM_RSC_STATE_FREE = 0,    /**< free state */
+       RM_RSC_STATE_SHARABLE,    /**< sharable state */
+       RM_RSC_STATE_SHARED,      /**< shared state */
+       RM_RSC_STATE_EXCLUSIVE    /**< exclusive state */
+} rm_resource_state_e;
+
+/**
+ * @enum    rm_return_code_e
+ * @brief         these values are used when the RM function returns
+ *
+ * contains return type, error message, and so on.
+ *
+ */
+typedef enum {
+       RM_OK,                                      // success
+       RM_ERROR,                                   // error
+       RM_ERROR_LOW_PRIORITY_CONSUMER_IS_USING,    // low priority consumer is already using the resource requested new consumer
+       RM_ERROR_TAKE_RESOURCE_FROM_OTHER_CONSUMER = RM_ERROR_LOW_PRIORITY_CONSUMER_IS_USING,
+       RM_OK_UHD_RESOURCE_CONFLICT,
+       RM_ERROR_HIGH_PRIORITY_CONSUMER_IS_USING
+} rm_return_code_e;
+
+/**
+ * @brief        device information for allocation
+ */
+typedef struct {
+       int device_id; /**< device id */
+       rm_requests_resource_state_e    requested_state; /**< requested resource state */
+} rm_device_s;
+
+/**
+ * @brief         device information when consumer requests the specific resource
+ */
+typedef struct {
+       int request_num; /**< number of devices to allocate */
+       rm_device_s *devices; /**< array of rm_device_s to allocate */
+} rm_requests_device_s;
+
+/**
+ *@brief        device information to be returned
+ */
+typedef struct {
+       int device_id; /**< device id */
+       const char *device_path; /**< device path */
+} rm_return_device_info_s;
+
+/**
+ * @brief        device information to be returned
+ */
+typedef struct {
+       int resources_num; /**< number of allocated devices */
+       int *device_ids; /**< array of allocated device id */
+       rm_return_device_info_s *devices; /**< allocated device information */
+} rm_return_device_s;
+
+ /**
+  * @brief error type when resource allocation request is failed
+  * @verstion 3.0
+  */
+typedef enum {
+       RM_ERR_TYPE_NONE = 0,
+       RM_ERR_TYPE_REQUEST_OF_INVISIBLE_PROCESS = 1,     /**< failed because invisible process requested resource */
+       RM_ERR_TYPE_REQUEST_OF_LOW_PRIORITY_PROCESS,      /**< failed because low priority process requested resource */
+       RM_ERR_TYPE_NOT_AVAILABLE_RESOURCE,               /**< failed because requested resource is not available */
+       RM_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST,    /**< failed because requested resource does not exist */
+       RM_ERR_TYPE_TAKE_RESOURCE_FROM_OTHER_CONSUMER,    /**< failed because higher priority consumer is using requested resource */
+       RM_ERR_TYPE_RESOURCE_EXHAUSTED,                   /**< failed because no more resource is allocatable */
+       RM_ERR_TYPE_INVALID_REQUEST,                      /**< failed because request is invalid */
+       RM_ERR_TYPE_NOT_PERMITTED                         /**< failed because the application is not permitted to use the requested resource */
+} rm_error_type_e;
+
+#define RM_REQUEST_RESOURCE_MAX 10
+#define RM_DEVICE_NAME_LEN_MAX 128
+
+/**
+ * @brief resource allocation request. The player needs to fill out requested resource in this form
+ */
+typedef struct {
+       int                                                request_num; /**< number of devices to allocate */
+       rm_rsc_category_e                      category_id[RM_REQUEST_RESOURCE_MAX]; /**< array of resource category id to allocate */
+       int                                                category_option[RM_REQUEST_RESOURCE_MAX]; /**< array of resource category id option to allocate */
+       rm_requests_resource_state_e   state[RM_REQUEST_RESOURCE_MAX]; /**< array of requested resource state */
+       char*                                           device_node[RM_REQUEST_RESOURCE_MAX]; /**< array of device path to allocate. Only fastvideo is supposed to use this */
+} rm_category_request_s;
+
+/**
+ * @brief information after resource allocation request
+ */
+typedef struct {
+       int                           allocated_num; /**< number of allocated resources */
+       int                           device_id[RM_REQUEST_RESOURCE_MAX]; /**< allocated device id */
+       char*                      device_node[RM_REQUEST_RESOURCE_MAX]; /**< allocated device node */
+       char*                      omx_comp_name[RM_REQUEST_RESOURCE_MAX]; /**< allocated omx component name */
+       rm_error_type_e    error_type; /**< error type in case of alloation failure */
+       char                        device_name[RM_REQUEST_RESOURCE_MAX][RM_DEVICE_NAME_LEN_MAX]; /**< allocated device name */
+} rm_device_return_s;
+
+/**
+ * @brief resource allocation request. The player needs to fill out requested resource in this form
+ */
+typedef struct {
+       int                 request_num;                                                        /**< number of resources to allocate */
+       int                 device_id[RM_REQUEST_RESOURCE_MAX];         /**< array of device id to allocate */
+       int                 option[RM_REQUEST_RESOURCE_MAX];            /**< deprecated - not used */
+} rm_device_request_s;
+
+/**
+* @brief resource conflict callback event type
+*/
+typedef enum {
+       RM_CALLBACK_TYPE_UNKNOWN = 1,                   /**< undefined callback event */
+       RM_CALLBACK_TYPE_RESOURCE_CONFLICT,             /**< common resource conflict */
+       RM_CALLBACK_TYPE_RESOURCE_CONFLICT_UD,  /**< resource conflict by ud device */
+} rm_callback_type;
+
+typedef rm_cb_result (*rm_resource_cb) (int handle, rm_callback_type event, rm_device_request_s *info, void *data);
+
+#define RM_CONSUMER_PID_MAX 5
+
+/**
+ * @brief consumer information
+ */
+typedef struct {
+       int player_type;                                /**< player type (not used) */
+       int main_priority;                              /**< main priority */
+       int sub_priority;                               /**< sub priority */
+       char app_id[1024];                              /**< application id associated with player */
+       int window_id;                                  /**< window id of application (not used) */
+       int pids[RM_CONSUMER_PID_MAX];  /**< process ids associated with player (not used) */
+       int app_pid;                                    /**< process id of application using player */
+} rm_consumer_info;
+
+/**
+* @brief query type
+* @version 2.4
+*/
+typedef enum {
+       RM_QUERY_NONE,       /**< not defined */
+       RM_QUERY_ALLOCATION, /**< query on resource allocation availability */
+       RM_QUERY_TERMINATE,  /**< query on process termination history by resource manager */
+       RM_QUERY_ACTIVE_DECS /**< query on the number of active decoders */
+} rm_query_type_e;
+
+struct rm_resource_list;
+typedef struct rm_resource_list *rm_resource_list_h;
+
+struct rm_resource;
+typedef struct rm_resource *rm_resource_h;
+
+struct rm_resource_state;
+typedef struct rm_resource_state *rm_resource_state_h;
+
+#endif // __RM_TYPE_H__
diff --git a/include_internal/RMShmCache.h b/include_internal/RMShmCache.h
new file mode 100644 (file)
index 0000000..0d57ad9
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+ * 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 __RC_SHM_CACHE_H__
+#define __RC_SHM_CACHE_H__
+#include <mutex>
+#include <boost/interprocess/managed_shared_memory.hpp>
+#include <boost/interprocess/allocators/allocator.hpp>
+#include <boost/interprocess/containers/string.hpp>
+#include <boost/unordered_map.hpp>
+#include <boost/functional/hash.hpp>
+
+#include <rm_type.h>
+#include <RMShm.h>
+
+namespace shared
+{
+       using segment = boost::interprocess::managed_shared_memory;
+       template <typename T>
+       using allocator = boost::interprocess::allocator<T, segment::segment_manager>;
+       using string = boost::container::basic_string<char, std::char_traits<char>, shared::allocator<char>>;
+       template <typename T1, typename T2>
+       using unordered_map = boost::unordered_map<T1, T2, boost::hash<T1>, std::equal_to<T1>, shared::allocator<std::pair<T1, T2>>>;
+}
+
+class RMShmCache
+{
+public:
+       static RMShmCache *GetInstance(void);
+
+       char *GetAppId(const int handle);
+       int FindScalerHWID(const int zone_id, int *hw_id);
+       int FindScalerDeviceID(const int virtual_id, int *device_id);
+       int FindPlayersUsingAudioMainOut(rm_resource_list_h *list);
+       int GetActiveAudioOut(const int handle, int *result);
+       bool Activated(const rm_shm_object_id id);
+       int ActivePlayer(const int handle, bool *result);
+
+private:
+       RMShmCache();
+       ~RMShmCache() = default;
+
+       bool Init(void);
+
+       bool ready_;
+       std::mutex init_mutex_;
+
+       shared::segment *shm_segment_;
+       shared::unordered_map<int, shared::string>* players_; // player id, app id
+       shared::unordered_map<int, CShmScaler>* scalers_; // device id, scaler
+       shared::unordered_map<int, CShmResource>* audio_outs_; // device id, audio main out
+       shared::unordered_map<int, bool>* active_state_; // object id, active or not
+};
+
+#endif //__RC_SHM_CACHE_H__
diff --git a/include_internal/rm_callback.h b/include_internal/rm_callback.h
new file mode 100644 (file)
index 0000000..5914eeb
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_CALLBACK_H__\r
+#define __RM_CALLBACK_H__\r
+\r
+#include <glib.h>\r
+#include <list>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+typedef struct {\r
+       int msg_type;       // callback message type\r
+       int cid;            // consumer id\r
+       int pid;            // process id\r
+       int conflicted_num; // conflicted resource num\r
+} rm_cb_head_s;\r
+\r
+typedef struct {\r
+       rm_conflict_event_cb cb;\r
+       void *data;\r
+} conflict_event_cb;\r
+\r
+typedef struct {\r
+       scaler_state_change_cb cb;\r
+       void *data;\r
+} scaler_state_cb;\r
+\r
+GMainLoop *rm_get_main_loop(void);\r
+GMainContext *rm_get_context(void);\r
+void rm_set_context(GMainContext *context);\r
+int rm_init_cb(int cid, rm_resource_cb cb, void *data);\r
+int rm_send_cb_msg(rm_cb_head_s *cb_head, int result);\r
+void rm_register_callback(int handle, rm_resource_cb cb, void *data, int fd, GSource *callback_handler, GIOChannel *gio);\r
+void rm_unregister_callback(int handle);\r
+\r
+int rm_add_state_change_cb(int category, resource_state_change_cb cb, void *data);\r
+int rm_remove_state_change_cb(int category, resource_state_change_cb cb);\r
+void rm_call_state_changed_cb(int category, int device_id, int state, int consumer_id, char *app_id);\r
+\r
+int rm_add_conflict_event_cb(rm_conflict_event_cb cb, void *data);\r
+int rm_remove_conflict_event_cb(rm_conflict_event_cb cb);\r
+std::list<conflict_event_cb*>& rm_get_conflict_event_cb_list(void);\r
+\r
+int rm_add_scaler_state_change_cb(scaler_state_change_cb cb, void *data);\r
+int rm_remove_scaler_state_change_cb(scaler_state_change_cb cb);\r
+void rm_call_scaler_state_changed_cb(rm_resource_list *scaler_list);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif// __RM_CALLBACK_H__\r
diff --git a/include_internal/rm_dbus.h b/include_internal/rm_dbus.h
new file mode 100644 (file)
index 0000000..0cf8140
--- /dev/null
@@ -0,0 +1,38 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_DBUS_H__\r
+#define __RM_DBUS_H__\r
+\r
+#include <glib.h>\r
+#include <gio/gio.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#define RM_DBUS_BUS_NAME "rscmgr.resource"\r
+#define RM_DBUS_INTERFACE_NAME "rscmgr.resource"\r
+#define RM_DBUS_OBJ_PATH "/rscmgr/resource"\r
+\r
+int rm_dbus_method_call(const char *method, GVariant *args, GVariant **result);\r
+int rm_dbus_method_call_async_with_no_reply(const char *method, GVariant *args);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+\r
+#endif //__RM_DBUS_H__
\ No newline at end of file
diff --git a/include_internal/rm_debug.h b/include_internal/rm_debug.h
new file mode 100644 (file)
index 0000000..4cfb311
--- /dev/null
@@ -0,0 +1,59 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_DEBUG_H__\r
+#define __RM_DEBUG_H__\r
+\r
+#include <rm_api.h>\r
+#include <dlog.h>\r
+#include <rm_internal.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+#ifdef LOG_TAG\r
+#undef LOG_TAG\r
+#endif //LOG_TAG\r
+\r
+#define LOG_TAG "RSC_MGR"\r
+\r
+\r
+#ifndef RM_DBG\r
+#define RM_DBG(fmt, args...) SLOGD(fmt, ##args)\r
+#endif\r
+\r
+#ifndef RM_INFO\r
+#define RM_INFO(fmt, args...) SLOGI(fmt, ##args)\r
+#endif\r
+\r
+#ifndef RM_WARN\r
+#define RM_WARN(fmt, args...) SLOGW(fmt, ##args)\r
+#endif\r
+\r
+#ifndef RM_ERR\r
+#define RM_ERR(fmt, args...) SLOGE(fmt, ##args)\r
+#endif\r
+\r
+const char *rm_convert_requested_state_enum_to_string(rm_requests_resource_state_e state_enum);\r
+const char *rm_convert_category_enum_to_string(rm_rsc_category_e category_enum);\r
+int is_symlink_file(const char *path);\r
+int _rc_get_capable_catgory_id(int handle, const char *app_id, int category_src);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif //__RM_DEBUG_H__\r
diff --git a/include_internal/rm_internal.h b/include_internal/rm_internal.h
new file mode 100644 (file)
index 0000000..9759fe0
--- /dev/null
@@ -0,0 +1,226 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_INTERNAL_H__\r
+#define __RM_INTERNAL_H__\r
+\r
+#include <rm_type.h>\r
+#include <glib.h>\r
+\r
+#define RM_RETURN_ERR_IF_NULL(a, msg) \\r
+               if (!a) \\r
+               { \\r
+                       RM_ERR("%s", msg); \\r
+                       return RM_ERROR; \\r
+               }\r
+\r
+#define RM_RETURN_NULL_IF_NULL(a, msg) \\r
+               if (!a) \\r
+               { \\r
+                       RM_ERR("%s", msg); \\r
+                       return NULL; \\r
+               }\r
+\r
+#define RM_RETURN_MINUS_IF_NULL(a, msg) \\r
+               if (!a) \\r
+               { \\r
+                       RM_ERR("%s", msg); \\r
+                       return -1; \\r
+               }\r
+\r
+#define RM_RETURN_IF_NULL(a, msg) \\r
+               if (!a) \\r
+               { \\r
+                       RM_ERR("%s", msg); \\r
+                       return; \\r
+               }\r
+\r
+#define RM_FREE(a) \\r
+               if (a) \\r
+               { \\r
+                       free(a); \\r
+                       a = NULL; \\r
+               }\r
+\r
+#define RM_RETURN_ERR_IF_LT(a, v, msg) \\r
+               if (a < v) \\r
+               { \\r
+                       RM_ERR("invalid value(%d)", a); \\r
+                       return RM_ERROR; \\r
+               }\r
+\r
+#define RM_RETURN_ERR_IF_GT(a, v, msg) \\r
+               if (a > v) \\r
+               { \\r
+                       RM_ERR("invalid value(%d)", a); \\r
+                       return RM_ERROR; \\r
+               }\r
+\r
+#define RM_DEVICE_NODE_LEN_MAX 4096\r
+#define RM_INT32_LEN 32\r
+\r
+/**\r
+ * @enum    rm_resource_internal_state_e\r
+ * @brief        Resource State\r
+ *             This state can be returned using RM API\r
+ */\r
+typedef enum {\r
+       RM_INTERNAL_STATE_FREE,\r
+       RM_INTERNAL_STATE_SHARABLE,\r
+       RM_INTERNAL_STATE_SHARED,\r
+       RM_INTERNAL_STATE_EXCLUSIVE,\r
+       RM_INTERNAL_STATE_ERROR\r
+} rm_resource_internal_state_e;\r
+\r
+typedef struct\r
+{\r
+       rm_rsc_category_e category_id;\r
+       int device_id;\r
+} rm_conflicted_resource_info_s;\r
+\r
+/**\r
+ * @brief      request data type\r
+ */\r
+typedef enum {\r
+       RM_REQUEST_DATA_TYPE_COMMON = 1,\r
+       RM_REQUEST_DATA_TYPE_REGISTER = (0x2 << 29),\r
+} rm_request_data_type;\r
+\r
+typedef enum {\r
+       RM_RESPONSE_DATA_TYPE_ALL = 0,\r
+       RM_RESPONSE_DATA_TYPE_COMMON = 1,\r
+       RM_RESPONSE_DATA_TYPE_REGISTER = (0x2 << 29)\r
+} rm_response_data_type;\r
+\r
+typedef enum {\r
+       RM_REQUEST_REGISTER,\r
+       RM_REQUEST_UNREGISTER,\r
+       RM_REQUEST_ALLOCATE_RESOURCE,\r
+       RM_REQUEST_RELEASE_RESOURCES,\r
+       RM_REQUEST_QUERY,\r
+       RM_REQUEST_SET_PRIORITY,\r
+       RM_REQUEST_SET_APPID,\r
+       RM_REQUEST_MAX,\r
+} rm_request_type_e;\r
+\r
+/**\r
+ * @struct    rm_category_s\r
+ * @brief        category information for allocation\r
+ */\r
+typedef struct\r
+{\r
+       rm_rsc_category_e    category_id;\r
+       int                  category_id_optional;\r
+       rm_requests_resource_state_e    requested_state;\r
+} rm_category_s;\r
+\r
+\r
+/**\r
+ * @struct rm_requests_category_s\r
+ * @brief resource type information when consumer requests resource category\r
+ *\r
+ * The rm_requests_category_s struct encapsulate the number of resource.\r
+ * resource type array. requests_state in the one data\r
+ *\r
+ */\r
+typedef struct\r
+{\r
+       int resources_num;\r
+       rm_category_s *resources_categories;\r
+} rm_requests_category_s;\r
+\r
+#define RM_APPID_LENGTH 256\r
+\r
+typedef struct {\r
+       long data_type;\r
+       int type;\r
+       int handle;\r
+       int pid;\r
+       int request_num;\r
+       int resource[RM_REQUEST_RESOURCE_MAX];\r
+       int resource_option[RM_REQUEST_RESOURCE_MAX];\r
+       int state[RM_REQUEST_RESOURCE_MAX];\r
+       int main_priority;\r
+       int sub_priority;\r
+       int app_pid;\r
+       char app_id[RM_APPID_LENGTH]; /* APPID */\r
+       int device_id[RM_REQUEST_RESOURCE_MAX];\r
+       int sub_type;\r
+       unsigned long time;\r
+} rm_msg_request;\r
+\r
+typedef struct {\r
+       long                    data_type;\r
+       int                     type;\r
+       int                     result;\r
+       int                     resource_num;\r
+       int                     resource[RM_REQUEST_RESOURCE_MAX];\r
+       rm_resource_internal_state_e resource_state[RM_REQUEST_RESOURCE_MAX];\r
+       int                     available;\r
+       int                     handle;\r
+       int                     error_type;\r
+       int                     pid;\r
+} rm_msg_response;\r
+\r
+struct rm_resource {\r
+       int id;\r
+       char *node;\r
+       int state;\r
+       int category_id;\r
+       int consumer_id;\r
+       char *app_id;\r
+       int virtual_id; //only for scaler\r
+       int source_id; //only for scaler\r
+       int max_rez; // max resolution only for scaler\r
+       int max_sampling_format; // only for scaler\r
+       int support_overlay; // only for scaler\r
+       int zone_id; // only for scaler\r
+       unsigned int framerate;\r
+       int cur_category_id; //only for scaler\r
+       unsigned int width;\r
+       unsigned int height;\r
+       bool android_app;\r
+};\r
+\r
+struct rm_resource_state {\r
+       int catId;\r
+       int devId;\r
+       int state;\r
+       int consumerId;\r
+       char *appId;\r
+};\r
+\r
+struct rm_resource_list {\r
+       int n_rsc;\r
+       GList *rsc_list;\r
+       GList *iter;\r
+};\r
+\r
+struct rm_conflict_resource {\r
+       int catId; // resource category id\r
+       int devId; // device id\r
+       int cId; // consumer id\r
+       const char *appId; // application id\r
+       int aZoneId; //application zone id\r
+       int rZoneId; //requester zone id\r
+};\r
+\r
+void rm_wait_for_server_ready(void);\r
+\r
+void rm_set_cpu_inheritance(void);\r
+void rm_clear_cpu_inheritance(void);\r
+\r
+#endif //__RM_INTERNAL_H__\r
diff --git a/include_internal/rm_msg.h b/include_internal/rm_msg.h
new file mode 100644 (file)
index 0000000..86dd15d
--- /dev/null
@@ -0,0 +1,33 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __RM_MSG_H__\r
+#define __RM_MSG_H__\r
+\r
+#include <rm_internal.h>\r
+\r
+#ifdef __cplusplus\r
+extern "C" {\r
+#endif\r
+\r
+int rm_send_msg(rm_msg_request  *data);\r
+int rm_receive_msg(rm_msg_response *response, int msg_type);\r
+void rm_construct_request_msg(rm_msg_request *request, int msg_type, int handle);\r
+\r
+#ifdef __cplusplus\r
+}\r
+#endif\r
+#endif //__RM_MSG_H__\r
diff --git a/packaging/resource-manager.spec b/packaging/resource-manager.spec
new file mode 100644 (file)
index 0000000..3152b3c
--- /dev/null
@@ -0,0 +1,79 @@
+Name:       resource-manager
+Summary:    Resource manager
+Version:    0.1
+Release:    0
+Group:      Multimedia/Libraries
+License:    Apache-2.0
+Source0:    %{name}-%{version}.tar.gz
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(dlog)
+BuildRequires:  pkgconfig(resource-information)
+BuildRequires:  pkgconfig(capi-system-info)
+BuildRequires:  pkgconfig(capi-system-resource)
+BuildRequires:  pkgconfig(libtzplatform-config)
+BuildRequires:  pkgconfig(glib-2.0)
+BuildRequires:  pkgconfig(gio-unix-2.0)
+BuildRequires:  pkgconfig(boost)
+BuildRequires:  pkgconfig(gmock)
+
+%define _pkgconfigdir %{_libdir}/pkgconfig
+%define _packagedir %{_libdir}/%{name}
+%define _includedir %{_libdir}/%{name}
+%define _bindir %{_packagedir}
+
+%define _utname resource-manager-ut
+
+%description
+This package manages the resources of Tizen device.
+
+%package devel
+Summary: Resource manager header files, static libraries
+Group: Development/Libraries
+Requires: %{name} = %{version}-%{release}
+Requires:  pkgconfig(resource-information)
+
+%description devel
+This package contains the header files and static libraries
+for Resource manager.
+
+%prep
+
+%setup -q
+
+export EVK_TV=n
+MAJORVER=`echo %{version} | awk 'BEGIN {FS="."}{print $1}'`
+
+cmake . \
+    -DCMAKE_INSTALL_PREFIX=%{_packagedir} \
+    -DPACKAGE_NAME=%{name} \
+    -DBINDIR=%{_bindir} \
+    -DINCLUDEDIR=%{_includedir} \
+    -DPKGCONFIG_INSTALL_DIR=%{_pkgconfigdir} \
+    -DVERSION=%{version} \
+    -DMAJORVERSION=${MAJORVER} \
+    -DLIBDIR=%{_libdir} \
+       -DRSCMGRPKGNAME=%{_utname} \
+    -DTZ_SYS_RW_APP=%{TZ_SYS_RW_APP} \
+       -DUNIT_TEST=1
+
+make %{?jobs:-j%jobs}
+
+%install
+rm -rf %{buildroot}
+%make_install
+
+%clean
+rm -rf %{buildroot}
+
+%files
+%defattr(-,root,root,-)
+%{_libdir}/*.so.*
+%{_bindir}/*
+%manifest resource-manager.manifest
+%license LICENSE.APLv2
+
+%files devel
+%defattr(-,root,root,-)
+%{_pkgconfigdir}/resource-manager.pc
+%{_includedir}/*.h
+%{_libdir}/*.so
diff --git a/resource-manager.manifest b/resource-manager.manifest
new file mode 100644 (file)
index 0000000..75b0fa5
--- /dev/null
@@ -0,0 +1,5 @@
+<manifest>
+    <request>
+        <domain name="_"/>
+    </request>
+</manifest>
diff --git a/resource-manager.pc.in b/resource-manager.pc.in
new file mode 100644 (file)
index 0000000..7ba499d
--- /dev/null
@@ -0,0 +1,12 @@
+prefix=/usr
+exec_prefix=${prefix}
+libdir=@LIBDIR@
+includedir=@INCLUDEDIR@
+
+Name: resource-manager
+Description: This package manages the resource of Tizen device
+Version: @VERSION@
+Requires: resource-information
+Libs: -L${libdir} -lresource-manager
+Cflags: -I${includedir} -I${libdir}
+CXXflags: -I${includedir} -I${libdir}
diff --git a/rscmgr-test.manifest b/rscmgr-test.manifest
new file mode 100644 (file)
index 0000000..677989e
--- /dev/null
@@ -0,0 +1,23 @@
+<manifest>
+    <define>
+        <domain name="rscmgr-test"/>
+        <request>
+            <smack request="systemd" type="rwx"/>
+            <smack request="system::vconf" type="arwxt"/>                      
+            <smack request="dbus" type="rwx"/>
+            <smack request="xorg" type="rwx"/>
+        </request>
+        <permit>
+            <smack permit="systemd" type="rx"/>
+            <smack permit="dbus" type="rwx"/>
+            <smack permit="xorg" type="rwx"/>
+        </permit>
+    </define>
+    <request>
+        <domain name="rscmgr-test"/>
+    </request>
+    <assign>
+        <filesystem path="/etc/*" label="_"/>
+        <filesystem path="/usr/lib/*" label="_"/>
+    </assign>
+</manifest>
diff --git a/src/RMShmCache.cpp b/src/RMShmCache.cpp
new file mode 100644 (file)
index 0000000..36cb180
--- /dev/null
@@ -0,0 +1,274 @@
+/*
+ * 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.
+ */
+
+#include <rm_debug.h>
+#include <rm_internal.h>
+#include <RMShmCache.h>
+
+#define ARRAY_SIZE(name) (sizeof(name)/sizeof(name[0]))
+
+static RMShmCache *instance_ = nullptr;
+static std::mutex instance_mutex_;
+
+// LCOV_EXCL_START
+
+RMShmCache *RMShmCache::GetInstance(void)
+{
+       if (instance_ == nullptr) {
+               std::lock_guard<std::mutex> guard(instance_mutex_);
+               if (instance_ == nullptr) {
+                       instance_ = new RMShmCache();
+               }
+       }
+       return instance_;
+}
+
+RMShmCache::RMShmCache(): ready_(false)
+{
+       Init();
+}
+
+bool RMShmCache::Init(void)
+{
+       if (ready_)
+               return true;
+
+       std::lock_guard<std::mutex> guard(init_mutex_);
+
+       try {
+               shm_segment_ = new shared::segment(boost::interprocess::open_read_only, "shm_rm");
+               players_ = shm_segment_->find<shared::unordered_map<int, shared::string>>("players").first;
+               scalers_ = shm_segment_->find<shared::unordered_map<int, CShmScaler>>("scalers").first;
+               audio_outs_ = shm_segment_->find<shared::unordered_map<int, CShmResource>>("audio_outs").first;
+               active_state_ = shm_segment_->find<shared::unordered_map<int, bool>>("active_state").first;
+       } catch (const std::exception &e) {
+               RM_ERR("failed to initialize shm (%s)", e.what());
+               return false;
+       }
+
+       ready_ = true;
+       return true;
+}
+
+char *RMShmCache::GetAppId(const int handle)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready (%d)", handle);
+               return nullptr;
+       }
+
+       if (!players_ || !Activated(RM_SHM_OBJ_PLAYER)) {
+               RM_ERR("object (players) not found or inactive");
+               return nullptr;
+       }
+
+       auto it = players_->find(handle);
+       if (it == players_->end()) {
+               RM_ERR("player not found (%d)", handle);
+               return nullptr;
+       }
+
+       RM_INFO("(%d:%s)", it->first, it->second.c_str());
+       return strdup(it->second.c_str());
+}
+
+typedef struct {
+       int device_id;
+       int hw_id;
+}scaler_id;
+
+static const scaler_id scaler_ids_[] = {
+       { RM_DEVICE_SCALER, 0},
+       { RM_DEVICE_SCALER_SUB, 1},
+       { RM_DEVICE_SCALER_SUB2, 2},
+       { RM_DEVICE_SCALER_SUB3, 3}
+};
+
+int RMShmCache::FindScalerHWID(const int zone_id, int *hw_id)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready (%d)", zone_id);
+               return RM_ERROR;
+       }
+
+       if (!scalers_ || !Activated(RM_SHM_OBJ_SCALER)) {
+               RM_ERR("object (scalers) not found or inactive");
+               return RM_ERROR;
+       }
+
+       for (unsigned int i = 0; i < ARRAY_SIZE(scaler_ids_); i++) {
+               auto it = scalers_->find(scaler_ids_[i].device_id);
+               if (it == scalers_->end())
+                       continue;
+               RM_INFO("requested zone id (%d)/device_id(%d)/zone id(%d)", zone_id, scaler_ids_[i].device_id, it->second.GetZoneID());
+               if (it->second.GetZoneID() != zone_id)
+                       continue;
+
+               *hw_id = scaler_ids_[i].hw_id;
+               RM_INFO("hw id (%d:%d)", zone_id, *hw_id);
+               return RM_OK;
+       }
+
+       *hw_id = -1;
+       RM_INFO("hw id (%d:%d)", zone_id, *hw_id);
+       return RM_OK;
+}
+
+int RMShmCache::FindScalerDeviceID(const int virtual_id, int *device_id)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready (%d)", virtual_id);
+               return RM_ERROR;
+       }
+
+       if (!scalers_ || !Activated(RM_SHM_OBJ_SCALER)) {
+               RM_ERR("object (scalers) not found or inactive");
+               return RM_ERROR;
+       }
+
+       for (unsigned int i = 0; i < ARRAY_SIZE(scaler_ids_); i++) {
+               auto it = scalers_->find(scaler_ids_[i].device_id);
+               if (it == scalers_->end())
+                       continue;
+               if (it->second.GetVirtualID() != virtual_id)
+                       continue;
+
+               *device_id = scaler_ids_[i].device_id;
+               return RM_OK;
+       }
+
+       *device_id = virtual_id;
+       return RM_OK;
+}
+
+int RMShmCache::FindPlayersUsingAudioMainOut(rm_resource_list_h *list)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready");
+               return RM_ERROR;
+       }
+
+       if (!audio_outs_ || !Activated(RM_SHM_OBJ_AUDIO_OUT)) {
+               RM_ERR("object (audio_outs) not found or inactive");
+               return RM_ERROR;
+       }
+
+       const int audio_main_out_devices[] = {
+               RM_DEVICE_AUDIO_MAIN_OUT,
+               RM_DEVICE_AUDIO_MAIN_OUT_SHARE0,
+               RM_DEVICE_AUDIO_MAIN_OUT_SHARE1
+       };
+
+       rm_resource_list *result = (rm_resource_list*) calloc(1, sizeof(rm_resource_list));
+       result->n_rsc = 0;
+
+       for (unsigned int i = 0; i < ARRAY_SIZE(audio_main_out_devices); i++) {
+               auto it = audio_outs_->find(audio_main_out_devices[i]);
+               if (it == audio_outs_->end())
+                       continue;
+               if (it->second.GetState() != RM_RSC_STATE_EXCLUSIVE)
+                       continue;
+
+               rm_resource *resource = (rm_resource*) calloc(1, sizeof(rm_resource));
+               resource->id = audio_main_out_devices[i];
+               resource->state = RM_RSC_STATE_EXCLUSIVE;
+               resource->consumer_id = it->second.GetPlayerID();
+               resource->app_id = GetAppId(it->second.GetPlayerID());
+
+               result->rsc_list = g_list_append(result->rsc_list, resource);
+       }
+
+       result->n_rsc = g_list_length(result->rsc_list);
+       result->iter = result->rsc_list;
+       *list = result;
+       RM_INFO("audio main out players found (%d)", result->n_rsc);
+       return RM_OK;
+}
+
+bool RMShmCache::Activated(const rm_shm_object_id id)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready");
+               return false;
+       }
+
+       auto it = active_state_->find(id);
+       return (it == active_state_->end()) ? false : it->second;
+}
+
+int RMShmCache::GetActiveAudioOut(const int handle, int *result)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready");
+               return RM_ERROR;
+       }
+
+       if (!audio_outs_ || !Activated(RM_SHM_OBJ_AUDIO_OUT)) {
+               RM_ERR("object (audio_outs) not found or inactive");
+               return RM_ERROR;
+       }
+
+       const int audio_out_devices[] = {
+               RM_DEVICE_AUDIO_MAIN_OUT,
+               RM_DEVICE_AUDIO_MAIN_OUT_SHARE0,
+               RM_DEVICE_AUDIO_MAIN_OUT_SHARE1,
+               RM_DEVICE_AUDIO_SUB_OUT
+       };
+
+       const int audio_main_out = 1;
+       const int audio_sub_out = 2;
+       int tmp = 0;
+
+       for (unsigned int i = 0; i < ARRAY_SIZE(audio_out_devices); i++) {
+               auto it = audio_outs_->find(audio_out_devices[i]);
+               if (it == audio_outs_->end())
+                       continue;
+               if (it->second.GetState() != RM_RSC_STATE_EXCLUSIVE)
+                       continue;
+               if (it->second.GetPlayerID() != handle)
+                       continue;
+
+               if (audio_out_devices[i] == RM_DEVICE_AUDIO_SUB_OUT)
+                       tmp |= audio_sub_out;
+               else
+                       tmp |= audio_main_out;
+       }
+
+       *result = tmp;
+       RM_INFO("(%d:%d)", handle, *result);
+       return RM_OK;
+}
+
+int RMShmCache::ActivePlayer(const int handle, bool *result)
+{
+       if (!ready_ && !Init()) {
+               RM_ERR("shm is not ready (%d)", handle);
+               return RM_ERROR;
+       }
+
+       if (!players_ || !Activated(RM_SHM_OBJ_PLAYER)) {
+               RM_ERR("object (players) not found or inactive");
+               return RM_ERROR;
+       }
+
+       auto it = players_->find(handle);
+       *result = (it != players_->end());
+
+       RM_INFO("(%d:%d)", handle, *result);
+       return RM_OK;
+}
+
+// LCOV_EXCL_STOP
diff --git a/src/rm_api.cpp b/src/rm_api.cpp
new file mode 100644 (file)
index 0000000..b077301
--- /dev/null
@@ -0,0 +1,442 @@
+/*
+ * 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.
+ */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sys/stat.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+#include <unistd.h>
+#include <assert.h>
+
+#include <glib.h>
+#include <gio/gio.h>
+
+#include <fcntl.h>
+#include <iostream>
+#include <ri-module-api.h>
+
+#include <rm_api.h>
+#include <rm_module_api.h>
+#include <rm_debug.h>
+#include <rm_callback.h>
+#include <rm_msg.h>
+#include <rm_internal.h>
+#include <rm_dbus.h>
+
+using namespace std;
+
+#ifndef PR_TASK_PERF_USER_TRACE
+#define PR_TASK_PERF_USER_TRACE 666
+#endif
+
+#define RM_HANDLE_COMMON 100
+#define RM_DEFAULT_PRIORITY 100
+
+int rm_register(rm_resource_cb cb, void *data, int *handle, rm_consumer_info *consumer_info)
+{
+       RM_RETURN_ERR_IF_NULL(cb, "invalid cb");
+       ri_init();
+       rm_wait_for_server_ready();
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+
+       rm_construct_request_msg(&msg, RM_REQUEST_REGISTER, -1);
+
+       if (consumer_info != NULL) {
+               msg.main_priority = consumer_info->main_priority;
+               msg.sub_priority = consumer_info->sub_priority;
+               msg.app_pid = consumer_info->app_pid;
+
+               int len = strlen(consumer_info->app_id);
+
+               if (len >= RM_APPID_LENGTH) {
+                       RM_ERR("appid[%s] is too long", consumer_info->app_id);
+                       return RM_ERROR;
+               }
+
+               strncpy(msg.app_id, consumer_info->app_id, RM_APPID_LENGTH);
+               msg.app_id[RM_APPID_LENGTH - 1] = '\0';
+       }
+
+       RM_INFO("request for registration");
+
+       msg.main_priority = (msg.main_priority == 0) ? RM_DEFAULT_PRIORITY : msg.main_priority;
+
+       rm_set_cpu_inheritance();
+
+       RM_INFO("send msg (%p)...", &msg);
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("failed to send message");
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK) {
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       if (response.result != RM_OK) {
+               RM_ERR("failed to get result(%d)", response.result);
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       RM_DBG("registered handle (%d)", response.handle);
+
+       *handle = response.handle;
+
+       if (rm_init_cb(response.handle, cb, data) != RM_OK) {
+               rm_unregister(response.handle);
+               RM_ERR("failed to init cb (%d)", response.handle);
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_clear_cpu_inheritance();
+       return RM_OK;
+}
+
+int rm_unregister(int handle)
+{
+       RM_RETURN_ERR_IF_LT(handle, 0, "invalid handle");
+
+       //trace_begin("[RSC_MGR] rm_deallocate_resources (handle:%d)", handle);
+       //trace_end();
+
+       rm_wait_for_server_ready();
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+
+       rm_construct_request_msg(&msg, RM_REQUEST_UNREGISTER, handle);
+
+       rm_set_cpu_inheritance();
+
+       RM_INFO("send msg (%p)...", &msg);
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("handle(%d) failed to send message", handle);
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK) {
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       if (response.result != RM_OK) {
+               RM_ERR("handle(%d) failed to get result(%d)", handle, response.result);
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_unregister_callback(handle);
+       rm_clear_cpu_inheritance();
+
+       RM_INFO("handle(%d) unregister result(%d)", handle, response.result);
+       return RM_OK;
+}
+
+int rm_allocate_resources(int handle, const rm_category_request_s *requests, rm_device_return_s *return_devices)
+{
+       int idx = 0;
+       RM_RETURN_ERR_IF_LT(handle, 0, "invalid handle");
+       RM_RETURN_ERR_IF_NULL(requests, "invalid requests");
+       RM_RETURN_ERR_IF_NULL(return_devices, "invalid return_devices");
+       RM_RETURN_ERR_IF_GT(requests->request_num, RM_REQUEST_RESOURCE_MAX, "invalid requests");
+
+       RM_INFO("Request for Allocation handle[%d] / pid[%d] / requested #[%d]",
+                               handle, getpid(), requests->request_num);
+
+       for (idx=0; idx < requests->request_num; idx++)
+               RM_INFO("(%d) CatID[%d-%s] / CatOpt[%d]",
+               idx + 1, requests->category_id[idx], rm_convert_category_enum_to_string(requests->category_id[idx]), requests->category_option[idx]);
+
+       rm_wait_for_server_ready();
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+
+       rm_construct_request_msg(&msg, RM_REQUEST_ALLOCATE_RESOURCE, handle);
+
+       msg.request_num = requests->request_num;
+
+       for (idx = 0; idx < msg.request_num; idx++) {
+               msg.resource[idx] = requests->category_id[idx];
+               msg.resource_option[idx] = requests->category_option[idx];
+               msg.state[idx] = requests->state[idx];
+               msg.device_id[idx] = (requests->device_node[idx] != NULL) ? ri_get_device_id(requests->device_node[idx]) : RM_DEVICE_NONE;
+               RM_INFO("[#%d] category id %d category option %d state %d device node %d", idx, msg.resource[idx], msg.resource_option[idx], msg.state[idx], msg.device_id[idx]);
+       }
+
+       RM_WARN("send msg (%p)...", &msg);
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("failed to send message");
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK) {
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       if (response.result != RM_OK) {
+               RM_WARN("RETURNED [%d] ERR_TYPE [%d]", response.result, response.error_type);
+               return_devices->error_type = (rm_error_type_e) response.error_type;
+               rm_clear_cpu_inheritance();
+               return response.result;
+       }
+
+       /* resource info got from server */
+       return_devices->allocated_num = response.resource_num;
+
+       const char *device_name = NULL;
+
+       for (idx = 0; idx < response.resource_num; idx++) {
+               return_devices->device_id[idx] = response.resource[idx];
+               ri_get_device_path_by_device_id(return_devices->device_id[idx], &(return_devices->device_node[idx]));
+               ri_get_omx_comp_name_by_device_id(return_devices->device_id[idx], &(return_devices->omx_comp_name[idx]));
+               device_name = ri_get_device_name_by_device_id(return_devices->device_id[idx]);
+               snprintf(return_devices->device_name[idx], RM_DEVICE_NAME_LEN_MAX, "%s", (device_name) ? device_name : "");
+       }
+
+       RM_WARN("Request for Allocation CID[%d] / PID[%d] / REQUESTED_RSC_NUM[%d] : SUCCESS", handle, getpid(), requests->request_num);
+
+       for (idx = 0; idx < return_devices->allocated_num; idx++) {
+               RM_INFO("(%d) CatID[%d] / Opt[%d] / DevID[%d ] / DevName[%s : %s : %s] ", idx,
+                       requests->category_id[idx],
+                       requests->category_option[idx],
+                       return_devices->device_id[idx],
+                       return_devices->device_node[idx],
+                       return_devices->omx_comp_name[idx],
+                       return_devices->device_name[idx]);
+       }
+
+       return RM_OK;
+}
+
+int rm_deallocate_resources(int handle, rm_device_request_s *requests)
+{
+       int idx = 0;
+       RM_INFO("request for deallocate handle(%d)", handle);
+
+       RM_RETURN_ERR_IF_LT(handle, 0, "invalid handle");
+       RM_RETURN_ERR_IF_NULL(requests, "invalid requests");
+       RM_RETURN_ERR_IF_GT(requests->request_num, RM_REQUEST_RESOURCE_MAX, "invalid requests");
+
+       rm_wait_for_server_ready();
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+
+       rm_construct_request_msg(&msg, RM_REQUEST_RELEASE_RESOURCES, handle);
+
+       msg.request_num = requests->request_num;
+
+       for (idx = 0; idx < msg.request_num; idx++)
+               msg.resource[idx] = requests->device_id[idx];
+
+       RM_INFO("send msg (%p)...", &msg);
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("failed to send message");
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK) {
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       if (response.result != RM_OK) {
+               RM_WARN("ERROR RETURNED[%d]", response.result);
+               rm_clear_cpu_inheritance();
+               return response.result;
+       }
+
+       return RM_OK;
+}
+
+int rm_query(int handle, rm_query_type_e query_type, rm_category_request_s *requests, int *result)
+{
+       int idx;
+       RM_RETURN_ERR_IF_LT(handle, 0, "invalid handle");
+       RM_RETURN_ERR_IF_NULL(requests, "invalid requests");
+       RM_RETURN_ERR_IF_GT(requests->request_num, RM_REQUEST_RESOURCE_MAX, "invalid requests");
+
+       RM_INFO("Request for Query(%d) handle[%d]/pid[%d]/requested[%d]",
+                               query_type, handle, getpid(), requests->request_num);
+
+       for (idx = 0; idx < requests->request_num; idx++) {
+               RM_INFO("requested (%d) CatID[%d-%s]/CatOpt[%d]/State(%s)", idx + 1, requests->category_id[idx], rm_convert_category_enum_to_string(requests->category_id[idx]), 
+                       requests->category_option[idx], rm_convert_requested_state_enum_to_string(requests->state[idx]));
+       }
+
+       rm_wait_for_server_ready();
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+
+       rm_construct_request_msg(&msg, RM_REQUEST_QUERY, handle);
+       msg.sub_type = query_type;
+
+       msg.request_num = requests->request_num;
+
+       for (idx = 0; idx < msg.request_num; idx++) {
+               msg.resource[idx] = requests->category_id[idx];
+               msg.resource_option[idx] = requests->category_option[idx];
+               msg.state[idx] = requests->state[idx];
+       }
+
+       rm_set_cpu_inheritance();
+
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("failed to send message");
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK) {
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       if (response.result != RM_OK) {
+               RM_ERR("ERROR RETURNED[%d]", response.result);
+               rm_clear_cpu_inheritance();
+               return response.result;
+       }
+
+       *result = (int)response.available;
+
+       if (!response.available)
+               RM_INFO("query result : false (cannot use resources)");
+       else
+               RM_INFO("query result : true (can use resources)");
+
+       rm_clear_cpu_inheritance();
+       return RM_OK;
+}
+
+int rm_set_priority(int handle, int priority)
+{
+       RM_RETURN_ERR_IF_LT(handle, 0, "invalid handle");
+
+       RM_INFO("Request for Setting Priority handle[%d]/pid[%d]/priority[%d]", handle, getpid(), priority);
+
+       rm_wait_for_server_ready();
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+
+       rm_construct_request_msg(&msg, RM_REQUEST_SET_PRIORITY, handle);
+
+       msg.main_priority = priority;
+
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("failed to send message");
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK)
+               return RM_ERROR;
+
+       if (response.result != RM_OK) {
+               RM_ERR("ERROR RETURNED[%d]", response.result);
+               return response.result;
+       }
+
+       return RM_OK;
+}
+
+int rm_set_app_id(int handle, char *app_id)
+{
+       int len, buf_size;
+
+       RM_RETURN_ERR_IF_LT(handle, 0, "invalid handle");
+       RM_RETURN_ERR_IF_NULL(app_id, "invalid app_id");
+
+       RM_INFO("Request for Setting APPID handle[%d]/pid[%d]/appid[%s]", handle, getpid(), app_id);
+
+       rm_wait_for_server_ready();
+
+       len = strlen(app_id);
+
+       if (len >= RM_APPID_LENGTH) {
+               RM_ERR("appid[%s] is too long", app_id);
+               return RM_ERROR;
+       }
+
+       rm_msg_request msg;
+       memset(&msg, 0, sizeof(msg));
+       buf_size = sizeof(msg.app_id);
+
+       rm_construct_request_msg(&msg, RM_REQUEST_SET_APPID, handle);
+
+       strncpy(msg.app_id, app_id, buf_size);
+       msg.app_id[buf_size - 1] = '\0';
+
+       RM_INFO("intput[%s] / [%s]", app_id, msg.app_id);
+
+       rm_set_cpu_inheritance();
+
+       if (rm_send_msg(&msg) != RM_OK) {
+               RM_ERR("failed to send message");
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       rm_msg_response response;
+       memset(&response, 0, sizeof(rm_msg_response));
+
+       if (rm_receive_msg(&response, msg.data_type) != RM_OK) {
+               rm_clear_cpu_inheritance();
+               return RM_ERROR;
+       }
+
+       if (response.result != RM_OK) {
+               RM_ERR("ERROR RETURNED[%d]", response.result);
+               rm_clear_cpu_inheritance();
+               return response.result;
+       }
+
+       rm_clear_cpu_inheritance();
+
+       return RM_OK;
+}
diff --git a/src/rm_callback.cpp b/src/rm_callback.cpp
new file mode 100644 (file)
index 0000000..8bee3c2
--- /dev/null
@@ -0,0 +1,712 @@
+/*
+ * 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.
+ */
+
+#include <errno.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <poll.h>
+#include <unistd.h>
+#include <pthread.h>
+#include <assert.h>
+#include <list>
+
+#include <glib.h>
+
+#include <rm_debug.h>
+#include <rm_module_api.h>
+#include <rm_callback.h>
+
+#define RM_HANDLE_MAX 100
+
+#ifndef __CONSTRUCTOR__
+#define __CONSTRUCTOR__ __attribute__ ((constructor))
+#endif
+
+#ifndef PR_TASK_PERF_USER_TRACE
+#define PR_TASK_PERF_USER_TRACE 666
+#endif
+
+#define IS_SMACK_READY (access("/tmp/smack_early_ready", F_OK) == 0)
+
+typedef struct {
+       int handle;
+       rm_resource_cb cb;
+       void *data;
+       int is_used;
+       int fd; //fd to FIFO from Server to Client
+       GSource *callback_handler;
+       GIOChannel *gio;
+} rm_cb_handle_s;
+
+static rm_cb_handle_s rm_cb_info[RM_HANDLE_MAX];
+
+static pthread_mutex_t rm_cb_mutex = PTHREAD_MUTEX_INITIALIZER;
+
+static GMainLoop *rm_client_loop = NULL;
+static GMainContext *rm_client_context = NULL;
+
+static void rm_add_main_loop(GMainLoop *loop)
+{
+       rm_client_loop = loop;
+}
+
+GMainLoop *rm_get_main_loop(void)
+{
+       return rm_client_loop;
+}
+
+gboolean _watchdog_cb(gpointer data)
+{
+       RM_INFO("watchdog notified");
+       return G_SOURCE_CONTINUE;
+}
+
+static gpointer rm_run_loop(gpointer data)
+{
+       RM_INFO("Run RM client thread");
+       GMainLoop *main_loop = rm_get_main_loop();
+
+       if (main_loop != NULL)
+               g_main_loop_run(main_loop);
+
+       RM_INFO("RM client thread finished\n");
+       return NULL;
+}
+
+int _create_event_loop(void)
+{
+       GMainContext *rm_client_ctx = NULL;
+
+       rm_client_ctx = g_main_context_new();
+       rm_set_context(rm_client_ctx);
+
+       GMainLoop *main_loop = g_main_loop_new(rm_client_ctx, FALSE);
+       rm_add_main_loop(main_loop);
+
+       GThread *rm_thrd = g_thread_new("rm_client", rm_run_loop, NULL);
+
+       if (rm_thrd == NULL) {
+               // LCOV_EXCL_START
+               g_main_loop_unref(main_loop);
+               RM_ERR("Failed to create new thread");
+               return RM_ERROR;
+               // LCOV_EXCL_STOP
+       }
+
+       return RM_OK;
+
+}
+
+int _create_cb_root_dir(void)
+{
+       const char *cb_dir_path = "/run/rsc_mgr";
+
+       mode_t pmask;
+       struct stat stat_info;
+
+       if (stat(cb_dir_path, &stat_info) == 0) // On Success zero returned, exists
+               return RM_OK;
+
+// LCOV_EXCL_START
+       mode_t dir_mode = 0666 | 0111;
+       pmask = umask(0);
+
+       if (mkdir(cb_dir_path, dir_mode) !=0) {
+               RM_ERR("failed to create cb directory (%d)", errno);
+               umask(pmask);
+               return RM_ERROR;
+       }
+       chmod(cb_dir_path, dir_mode);
+       umask(pmask);
+
+       return RM_OK;
+// LCOV_EXCL_STOP
+}
+
+int _create_FIFO_s2c(int pid, int cid)
+{
+       struct stat stat_info;
+       mode_t pmask;
+       char cb_path_s2c[256] = {0, };
+       //3.0
+       snprintf(cb_path_s2c, 256, "/run/rsc_mgr/%d.%d.s2c.cb", pid, cid);
+
+       if (stat(cb_path_s2c, &stat_info) == 0) {
+               return RM_OK;
+       }
+
+       pmask = umask(0);
+
+       if (mknod(cb_path_s2c, S_IFIFO|0666, 0)) {
+               RM_ERR("failed to create cb for S2C(%s)-(%d)", cb_path_s2c, errno);
+               umask(pmask);
+               return RM_ERROR;
+       }
+
+       umask(pmask);
+
+       return RM_OK;
+
+}
+
+int _remove_FIFO_s2c(int pid, int cid)
+{
+       struct stat stat_info;
+       char cb_path_s2c[256] = {0, };
+       //3.0
+       snprintf(cb_path_s2c, 256, "/run/rsc_mgr/%d.%d.s2c.cb", pid, cid);
+
+       if (stat(cb_path_s2c, &stat_info) != 0) {
+               return RM_OK;
+       }
+
+       if (remove(cb_path_s2c) != 0) {
+               RM_ERR("failed to remove cb for S2C(%s)-(%d)", cb_path_s2c, errno);
+               return RM_ERROR;
+       }
+
+       RM_INFO("Removed cb for S2C(%s)", cb_path_s2c);
+       return RM_OK;
+
+}
+
+void rm_register_callback(int handle, rm_resource_cb cb, void *data, int fd, GSource *callback_handler, GIOChannel *gio)
+{
+       for (int i = 0; i < RM_HANDLE_MAX; i++) {
+               if (rm_cb_info[i].is_used == 0) {
+                       rm_cb_info[i].is_used = 1;
+                       rm_cb_info[i].handle = handle;
+                       rm_cb_info[i].cb = cb;
+                       rm_cb_info[i].data = data;
+                       rm_cb_info[i].fd = fd;
+                       rm_cb_info[i].callback_handler = callback_handler;
+                       rm_cb_info[i].gio = gio;
+                       return;
+               }
+       }
+
+       RM_ERR("error! there is no empty slot");
+}
+
+void rm_unregister_callback(int handle)
+{
+       pthread_mutex_lock(&rm_cb_mutex);
+
+       for (int i = 0; i < RM_HANDLE_MAX; i++) {
+               if (rm_cb_info[i].handle == handle) {
+                       rm_cb_info[i].handle = 0;
+                       rm_cb_info[i].cb = NULL;
+                       rm_cb_info[i].data = NULL;
+                       rm_cb_info[i].is_used = 0;
+
+                       g_io_channel_unref(rm_cb_info[i].gio);
+
+                       if ((rm_cb_info[i].callback_handler != NULL) && !g_source_is_destroyed(rm_cb_info[i].callback_handler))         {
+                               g_source_destroy(rm_cb_info[i].callback_handler);
+                               g_source_unref(rm_cb_info[i].callback_handler);
+                       }
+
+                       rm_cb_info[i].callback_handler = NULL;
+
+                       if (close(rm_cb_info[i].fd)!= 0)
+                               RM_ERR("error! on close FIFO(%d)..errno(%d)", rm_cb_info[i].fd, errno);
+
+                       rm_cb_info[i].fd = -1;
+
+                       _remove_FIFO_s2c(getpid(), handle);
+
+                       pthread_mutex_unlock(&rm_cb_mutex);
+                       return;
+               }
+       }
+
+       RM_ERR("error! there is no callback registered by handle(%d)", handle);
+
+       pthread_mutex_unlock(&rm_cb_mutex);
+}
+
+static bool _is_valid_fd(int fd)
+{
+       for (int i = 0; i < RM_HANDLE_MAX; i++) {
+               if (fd == rm_cb_info[i].fd && rm_cb_info[i].is_used) {
+                       RM_WARN("handle : (%d), fd : (%d)", i, fd);
+                       return true;
+               }
+       }
+       RM_ERR("invalid fd : (%d)", fd);
+       return false;
+}
+
+static int _parse_common_callback(int fd, rm_cb_head_s cb_head, rm_device_request_s *requests)
+{
+       int conflicted_resource_num = cb_head.conflicted_num;
+       int res_size = sizeof(int) * conflicted_resource_num;
+       int *resources = (int*) calloc(1, res_size);
+       assert(resources);
+
+       int rbyte = read(fd, resources, res_size);
+       if ((rbyte <= 0) || (rbyte != res_size)) {
+               RM_ERR("Unexpected read byte size (%d)", rbyte);
+               free(resources);
+               return RM_ERROR;
+       }
+
+       for (int i = 0; i < conflicted_resource_num; i++)
+               RM_WARN("[#%d / #%d] conflicted resource id : %d", i, conflicted_resource_num, resources[i]);
+
+       requests->request_num = conflicted_resource_num;
+
+       for (int i = 0; i < requests->request_num; i++)
+               requests->device_id[i] = resources[i];
+
+       free(resources);
+       return RM_OK;
+}
+
+static gboolean rm_gio_cb(GIOChannel *src, GIOCondition cond, gpointer data)
+{
+       RM_WARN("callback called");
+
+       rm_cb_head_s cb_head;
+
+       int fd = g_io_channel_unix_get_fd(src);
+       int rbyte = read(fd, &cb_head, sizeof(cb_head));
+
+       if ((rbyte <= 0) || (rbyte != sizeof(cb_head))) {
+               RM_ERR("fd(%d) unexpected size (%d:%zu)/err(%d:%d:%d)", fd, rbyte, sizeof(cb_head), (cond & G_IO_ERR), (cond & G_IO_HUP), (cond & G_IO_NVAL));
+               if (cond & (G_IO_ERR | G_IO_HUP | G_IO_NVAL))
+                       return G_SOURCE_REMOVE;
+               return _is_valid_fd(fd) ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
+       }
+
+       RM_WARN("TYPE[%d] / CID[%d] / PID[%d] / CONFLICTED[%d]", cb_head.msg_type, cb_head.cid, cb_head.pid, cb_head.conflicted_num);
+
+       if ((cb_head.conflicted_num <= 0) || (cb_head.conflicted_num > RM_REQUEST_RESOURCE_MAX)) {
+               RM_ERR("fd(%d) invalid data, conflicted_num(%d)", fd, cb_head.conflicted_num);
+               return _is_valid_fd(fd) ? G_SOURCE_CONTINUE : G_SOURCE_REMOVE;
+       }
+
+       rm_device_request_s requests;
+       memset(&requests, 0, sizeof(rm_device_request_s));
+
+       if (_parse_common_callback(fd, cb_head, &requests))
+               return G_SOURCE_CONTINUE;
+
+       rm_resource_cb cb = NULL;
+       void *cb_data = NULL;
+
+       pthread_mutex_lock(&rm_cb_mutex);
+
+       for (int i = 0; i < RM_HANDLE_MAX; i++) {
+               if (rm_cb_info[i].handle == cb_head.cid) {
+                       cb = rm_cb_info[i].cb;
+                       cb_data = rm_cb_info[i].data;
+                       break;
+               }
+       }
+
+       pthread_mutex_unlock(&rm_cb_mutex);
+
+       RM_WARN("call client callback CID[%d]/PID[%d]", cb_head.cid, cb_head.pid);
+
+       if (cb == NULL) {
+               RM_ERR("callback was unregistered CID[%d]/PID[%d]", cb_head.cid, cb_head.pid);
+               return G_SOURCE_CONTINUE;
+       }
+
+       rm_callback_type cb_type = RM_CALLBACK_TYPE_UNKNOWN;
+
+       cb_type = (rm_callback_type) (cb_head.msg_type);
+
+       int cb_result = cb(cb_head.cid, cb_type, &requests, cb_data);
+
+       RM_WARN("client callback CID[%d]/PID[%d] returned. result[%d]", cb_head.cid, cb_head.pid, cb_result);
+       return G_SOURCE_CONTINUE;
+}
+
+GMainContext *rm_get_context(void)
+{
+       return rm_client_context;
+}
+
+void rm_set_context(GMainContext *context)
+{
+       rm_client_context = context;
+}
+
+int rm_init_cb(int cid, rm_resource_cb cb, void *data)
+{
+       pthread_mutex_lock(&rm_cb_mutex);
+       int pid = getpid();
+
+       // initialize event loop to receive callback message from server
+       GMainContext *rm_client_ctx = rm_get_context();
+
+       if (rm_client_ctx == NULL) {
+               if (_create_event_loop() != RM_OK) {
+                       pthread_mutex_unlock(&rm_cb_mutex);
+                       return RM_ERROR;
+               }
+       }
+
+       // check and create root directory required for FIFO
+       if (_create_cb_root_dir() != RM_OK) {
+               pthread_mutex_unlock(&rm_cb_mutex);
+               return RM_ERROR;
+       }
+
+       // check and create FIFO (server to client)
+       if (_create_FIFO_s2c(pid, cid) != RM_OK) {
+               pthread_mutex_unlock(&rm_cb_mutex);
+               return RM_ERROR;
+       }
+
+       char cb_path_s2c[256] = {0, };
+       int fd = -1;
+       GSource *rm_cb_handler = NULL;
+       //3.0
+       snprintf(cb_path_s2c, 256, "/run/rsc_mgr/%d.%d.s2c.cb", pid, cid);
+
+       if ((fd = open(cb_path_s2c, O_RDWR|O_NONBLOCK)) < 0) {
+               RM_ERR("open error (%s), errno(%d)\n", cb_path_s2c, errno);
+               pthread_mutex_unlock(&rm_cb_mutex);
+               return RM_ERROR;
+       }
+
+       //register as a GSource
+       GIOChannel *gio = g_io_channel_unix_new(fd);
+
+       if (gio == NULL) {
+               RM_ERR("failed to create a new GIOChannel");
+               pthread_mutex_unlock(&rm_cb_mutex);
+               close(fd);
+               return RM_ERROR;
+       }
+
+       g_io_channel_set_flags(gio, G_IO_FLAG_NONBLOCK, NULL);
+       rm_cb_handler = g_io_create_watch(gio, G_IO_IN);
+
+       g_source_set_callback(rm_cb_handler, ((GSourceFunc) (void (*)(void)) (rm_gio_cb)), NULL, NULL);
+       RM_INFO("set callback to rm_cb_handler(%p), fd=(%d), rm_client_ctx(%p)", rm_cb_handler, fd, rm_get_context());
+       g_source_attach(rm_cb_handler, rm_get_context());
+
+       // register callback into internal structure
+       rm_register_callback(cid, cb, data, fd, rm_cb_handler, gio);
+
+       pthread_mutex_unlock(&rm_cb_mutex);
+       return RM_OK;
+
+}
+
+// LCOV_EXCL_START
+static GHashTable *htable_state_cb = NULL;
+
+typedef struct {
+       int category;
+       GList *list;
+} rm_category_cb;
+
+typedef struct {
+       resource_state_change_cb cb;
+       void *data;
+} rm_state_change_cb;
+
+void _free_rm_state_change_cb(gpointer data)
+{
+       if (!data)
+               return;
+
+       rm_state_change_cb *state_cb = (rm_state_change_cb*) data;
+       RM_FREE(state_cb);
+}
+
+static void _destroy_data(gpointer data)
+{
+       if (!data)
+               return;
+
+       rm_category_cb *category_cb = (rm_category_cb*) data;
+       g_list_free_full(category_cb->list, _free_rm_state_change_cb);
+       RM_FREE(category_cb);
+}
+
+GHashTable *_get_state_change_cb_htable(void)
+{
+       if (!htable_state_cb)
+               htable_state_cb = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, _destroy_data);
+
+       return htable_state_cb;
+}
+
+
+rm_state_change_cb *_new_rm_state_change_cb(resource_state_change_cb cb, void *data)
+{
+       rm_state_change_cb *state_cb = (rm_state_change_cb*) calloc(1, sizeof(rm_state_change_cb));
+       assert(state_cb);
+
+       state_cb->cb = cb;
+       state_cb->data = data;
+
+       return state_cb;
+}
+
+static int _find_state_cb(GList *list, resource_state_change_cb cb, rm_state_change_cb **state_cb)
+{
+       RM_RETURN_MINUS_IF_NULL(list, "invalid list");
+       RM_RETURN_MINUS_IF_NULL(cb, "invalid cb");
+       RM_RETURN_MINUS_IF_NULL(state_cb, "invalid state_cb");
+
+       rm_state_change_cb *tmp_cb = NULL;
+       GList *tmp_list = g_list_first(list);
+
+       while(tmp_list) {
+               tmp_cb = (rm_state_change_cb*) tmp_list->data;
+               if (tmp_cb->cb == cb) {
+                       *state_cb = tmp_cb;
+                       return 0;
+               }
+               tmp_list = g_list_next(tmp_list);
+       }
+
+       return -1;
+}
+
+GList *rm_get_state_change_cb_list(int category)
+{
+       rm_category_cb *category_cb = (rm_category_cb*) g_hash_table_lookup(_get_state_change_cb_htable(), GINT_TO_POINTER(category));
+
+       if (!category_cb)
+               return NULL;
+
+       if (!category_cb->list)
+               return NULL;
+
+       return g_list_copy(category_cb->list);
+}
+
+void rm_call_state_changed_cb(int category, int device_id, int state, int handle, char *app_id)
+{
+       rm_category_cb *category_cb = (rm_category_cb*) g_hash_table_lookup(_get_state_change_cb_htable(), GINT_TO_POINTER(category));
+
+       if (!category_cb) {
+               RM_INFO("no callback (%d)", category);
+               return;
+       }
+
+       if (!category_cb->list) {
+               RM_INFO("no callback (%d)", category);
+               return;
+       }
+
+       GList *l;
+       struct rm_resource_state rsc_state;
+       rsc_state.catId = category;
+       rsc_state.devId = device_id;
+       rsc_state.state = state;
+       rsc_state.consumerId = handle;
+       rsc_state.appId = app_id;
+
+       for (l = category_cb->list; l; l = g_list_next(l)) {
+               rm_state_change_cb *state_change_cb = (rm_state_change_cb*) l->data;
+               RM_INFO("call cb(%p)", state_change_cb);
+               state_change_cb->cb(&rsc_state, state_change_cb->data);
+       }
+}
+
+int rm_add_state_change_cb(int category, resource_state_change_cb cb, void *data)
+{
+       rm_category_cb *category_cb = (rm_category_cb*) g_hash_table_lookup(_get_state_change_cb_htable(), GINT_TO_POINTER(category));
+       rm_state_change_cb *state_cb = NULL;
+
+       if (!category_cb) {
+               category_cb = (rm_category_cb*) calloc(1, sizeof(rm_category_cb));
+               assert(category_cb);
+               category_cb->category = category;
+               category_cb->list = g_list_append(category_cb->list, _new_rm_state_change_cb(cb, data));
+
+               g_hash_table_insert(_get_state_change_cb_htable(), GINT_TO_POINTER(category), category_cb);
+               RM_INFO("state change cb added (%d:%p) catcb(%p)", category, cb, category_cb);
+               return 0;
+       }
+
+       if (_find_state_cb(category_cb->list, cb, &state_cb) == 0) {
+               RM_ERR("already registered cb (%d:%p)", category, cb);
+               return -1;
+       }
+
+       category_cb->list = g_list_append(category_cb->list, _new_rm_state_change_cb(cb, data));
+       RM_INFO("state change cb added (%d:%p) l(%d)", category, cb, g_list_length(category_cb->list));
+       return 0;
+}
+
+int rm_remove_state_change_cb(int category, resource_state_change_cb cb)
+{
+       rm_category_cb *category_cb = (rm_category_cb*) g_hash_table_lookup(_get_state_change_cb_htable(), GINT_TO_POINTER(category));
+       rm_state_change_cb *found_cb = NULL;
+
+       if (!category_cb) {
+               RM_ERR("no cb registered for category (%d:%p)", category, cb);
+               return -1;
+       }
+
+       if (_find_state_cb(category_cb->list, cb, &found_cb) < 0) {
+               RM_ERR("not registered cb (%d:%p)", category, cb);
+               return -1;
+       }
+
+       category_cb->list = g_list_remove(category_cb->list, found_cb);
+       RM_INFO("cb removed (%d:%p) l(%d)", category, cb, g_list_length(category_cb->list));
+
+       RM_FREE(found_cb);
+
+       if (g_list_length(category_cb->list) == 0) {
+               RM_INFO("all cbs removed for (%d) h(%d)", category, g_hash_table_size(_get_state_change_cb_htable()));
+               g_hash_table_remove(_get_state_change_cb_htable(), GINT_TO_POINTER(category));
+       }
+
+       return (int) g_hash_table_size(_get_state_change_cb_htable());
+}
+
+static std::list<conflict_event_cb*> conflict_event_cb_list;
+std::list<conflict_event_cb*>& rm_get_conflict_event_cb_list(void)
+{
+       return conflict_event_cb_list;
+}
+
+conflict_event_cb *_new_conflict_event_cb(rm_conflict_event_cb cb, void *data)
+{
+       conflict_event_cb *new_cb = (conflict_event_cb*)calloc(1, sizeof(conflict_event_cb));
+       assert(new_cb);
+       new_cb->cb = cb;
+       new_cb->data = data;
+       return new_cb;
+}
+
+void _free_conflict_event_cb(conflict_event_cb *cb)
+{
+       if (!cb)
+               return;
+
+       free(cb);
+       cb = NULL;
+}
+
+int rm_add_conflict_event_cb(rm_conflict_event_cb cb, void *data)
+{
+       std::list<conflict_event_cb*> &cb_list = rm_get_conflict_event_cb_list();
+
+       for (auto& it : cb_list) {
+               if (it->cb == cb)
+                       return -1;
+       }
+
+       cb_list.push_back(_new_conflict_event_cb(cb, data));
+       RM_INFO("callback added (%p)", cb);
+
+       return 0;
+}
+
+int rm_remove_conflict_event_cb(rm_conflict_event_cb cb)
+{
+       std::list<conflict_event_cb*> &cb_list = rm_get_conflict_event_cb_list();
+
+       for (auto it = cb_list.begin(); it != cb_list.end(); ++it) {
+               conflict_event_cb *tmp_cb = *it;
+               if (tmp_cb->cb == cb) {
+                       it = cb_list.erase(it);
+                       RM_INFO("removed cb (%p)", cb);
+                       _free_conflict_event_cb(tmp_cb);
+                       return cb_list.size();
+               }
+       }
+       return -1;
+}
+
+static std::list<scaler_state_cb *> scaler_state_change_cb_list;
+std::list<scaler_state_cb *>& rm_get_scaler_state_change_cb_list(void)
+{
+       return scaler_state_change_cb_list;
+}
+
+scaler_state_cb *_new_scaler_state_cb(scaler_state_change_cb cb, void *data)
+{
+       scaler_state_cb *new_cb = (scaler_state_cb *)calloc(1, sizeof(scaler_state_cb));
+       assert(new_cb);
+       new_cb->cb = cb;
+       new_cb->data = data;
+       return new_cb;
+}
+
+void _free_scaler_state_cb(scaler_state_cb *cb)
+{
+       if (!cb)
+               return;
+
+       free(cb);
+       cb = NULL;
+}
+
+int rm_add_scaler_state_change_cb(scaler_state_change_cb cb, void *data)
+{
+       std::list<scaler_state_cb *> &cb_list = rm_get_scaler_state_change_cb_list();
+
+       for (auto& it : cb_list) {
+               if (it->cb == cb)
+                       return -1;
+       }
+
+       cb_list.push_back(_new_scaler_state_cb(cb, data));
+       RM_INFO("callback added (%p)", cb);
+       return 0;
+}
+
+int rm_remove_scaler_state_change_cb(scaler_state_change_cb cb)
+{
+       std::list<scaler_state_cb *> &cb_list = rm_get_scaler_state_change_cb_list();
+
+       for (auto it = cb_list.begin(); it != cb_list.end(); ++it) {
+               scaler_state_cb *tmp_cb = *it;
+               if (tmp_cb->cb == cb) {
+                       it = cb_list.erase(it);
+                       RM_INFO("removed cb (%p)", cb);
+                       _free_scaler_state_cb(tmp_cb);
+                       return cb_list.size();
+               }
+       }
+       return -1;
+}
+
+void rm_call_scaler_state_changed_cb(rm_resource_list *scaler_list)
+{
+       std::list<scaler_state_cb *> cb_list = rm_get_scaler_state_change_cb_list();
+
+       for (auto &it : cb_list) {
+               RM_INFO("call cb(%p)", it->cb);
+               it->cb(scaler_list, it->data);
+       }
+}
+
+// LCOV_EXCL_STOP
+
+static void __CONSTRUCTOR__ module_init(void)
+{
+       memset(&rm_cb_info, 0, sizeof(rm_cb_handle_s)*RM_HANDLE_MAX);
+}
diff --git a/src/rm_dbus.cpp b/src/rm_dbus.cpp
new file mode 100644 (file)
index 0000000..509eeca
--- /dev/null
@@ -0,0 +1,131 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <stdint.h>\r
+#include <unistd.h>\r
+\r
+#include <rm_dbus.h>\r
+#include <rm_debug.h>\r
+\r
+// LCOV_EXCL_START\r
+\r
+static bool _wait_server_ready(void)\r
+{\r
+       const char *rsc_event_name = "/run/rsc_mgr_ready";\r
+\r
+       return access(rsc_event_name, F_OK) == 0;\r
+}\r
+\r
+static GDBusConnection* __dbus_get_connection()\r
+{\r
+       static GDBusConnection *conn = NULL;\r
+       GError *err = NULL;\r
+\r
+       if (conn)\r
+               return conn;\r
+\r
+       conn = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &err);\r
+       if (!conn)      {\r
+               RM_ERR("g_bus_get_sync() error (%s)", err->message);\r
+               g_error_free(err);\r
+               return NULL;\r
+       }\r
+\r
+       return conn;\r
+}\r
+\r
+void rm_set_cpu_inheritance(void)\r
+{\r
+       //resource_set_cpu_inheritance(0, "rscmgr-service", 1000);\r
+}\r
+\r
+void rm_clear_cpu_inheritance(void)\r
+{\r
+       //resource_clear_cpu_inheritance(0, "rscmgr-service");\r
+}\r
+\r
+int rm_dbus_method_call(const char *method, GVariant *args, GVariant **result)\r
+{\r
+       GError *err = NULL;\r
+       GVariant *reply = NULL;\r
+       GDBusConnection *conn = NULL;\r
+\r
+       if (!method) {\r
+               RM_ERR("Invalid Argument");\r
+               g_variant_unref(args);\r
+               return -1;\r
+       }\r
+\r
+       RM_INFO("Method call '%s'", method);\r
+\r
+       if (!_wait_server_ready()) {\r
+               RM_ERR("server is not ready yet");\r
+               g_variant_unref(args);\r
+               return -1;\r
+       }\r
+\r
+       conn = __dbus_get_connection();\r
+\r
+       if (!conn) {\r
+               g_variant_unref(args);\r
+               return -1;\r
+       }\r
+\r
+       rm_set_cpu_inheritance();\r
+       reply = g_dbus_connection_call_sync(conn, RM_DBUS_BUS_NAME, RM_DBUS_OBJ_PATH, RM_DBUS_INTERFACE_NAME,\r
+                                                                               method, args, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, &err);\r
+       rm_clear_cpu_inheritance();\r
+\r
+       if (!reply) {\r
+               RM_ERR("Method Call '%s' Failed (%s)", method, err->message);\r
+               g_error_free(err);\r
+               return -1;\r
+       }\r
+\r
+       if (result)\r
+               *result = reply;\r
+\r
+       return 0;\r
+}\r
+\r
+int rm_dbus_method_call_async_with_no_reply(const char *method, GVariant *args)\r
+{\r
+       if (!method) {\r
+               RM_ERR("Invalid Argument");\r
+               g_variant_unref(args);\r
+               return -1;\r
+       }\r
+\r
+       RM_INFO("Method call (async) '%s'", method);\r
+\r
+       if (!_wait_server_ready()) {\r
+               RM_ERR("server is not ready yet");\r
+               return -1;\r
+       }\r
+\r
+       GDBusConnection *conn = __dbus_get_connection();\r
+       if (!conn) {\r
+               g_variant_unref(args);\r
+               return -1;\r
+       }\r
+\r
+       g_dbus_connection_call(conn, RM_DBUS_BUS_NAME, RM_DBUS_OBJ_PATH, RM_DBUS_INTERFACE_NAME,\r
+                                                                               method, args, NULL, G_DBUS_CALL_FLAGS_NONE, -1, NULL, NULL, NULL);\r
+\r
+       return 0;\r
+}\r
+// LCOV_EXCL_STOP\r
diff --git a/src/rm_debug.cpp b/src/rm_debug.cpp
new file mode 100644 (file)
index 0000000..f3dde03
--- /dev/null
@@ -0,0 +1,128 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <rm_debug.h>\r
+#include <sys/types.h>\r
+#include <sys/stat.h>\r
+#include <unistd.h>\r
+\r
+// LCOV_EXCL_START\r
+const char *rm_convert_requested_state_enum_to_string(rm_requests_resource_state_e state_enum)\r
+{\r
+       switch(state_enum) {\r
+               case RM_STATE_PASSIVE:\r
+                       return "PASSIVE";\r
+               case RM_STATE_SHARABLE:\r
+                       return "SHARABLE";\r
+               case RM_STATE_EXCLUSIVE:\r
+                       return "EXCLUSIVE";\r
+               case RM_STATE_EXCLUSIVE_CONDITIONAL:\r
+                       return "EXCLUSIVE_CONDITIONAL";\r
+               case RM_STATE_EXCLUSIVE_AUTO:\r
+                       return "EXCLUSIVE_AUTO";\r
+               case RM_STATE_EXCLUSIVE_PREFERENCE:\r
+                       return "EXCLUSIVE_PREFERENCE";\r
+               default:\r
+                       return "NONE";\r
+       }\r
+}\r
+\r
+const char *rm_convert_category_enum_to_string(rm_rsc_category_e category_enum)\r
+{\r
+       switch(category_enum) {\r
+               case RM_CATEGORY_NONE:\r
+                       return "NONE";\r
+               case RM_CATEGORY_AUDIO_DECODER:\r
+                       return "Audio_Decoder";\r
+               case RM_CATEGORY_AUDIO_DECODER_PRIMARY:\r
+                       return "Audio_Decoder_Primary";\r
+               case RM_CATEGORY_AUDIO_EVENT_COMPRESS:\r
+                       return "Audio_Event_Compress";\r
+               case RM_CATEGORY_AUDIO_SPDIF_ES_OUTPUT:\r
+                       return "Not Defined Yet";\r
+               case RM_CATEGORY_VIDEO_DECODER:\r
+                       return "Video_Decoder";\r
+               case RM_CATEGORY_DEMUX:\r
+                       return "Demux_Main";\r
+               case RM_CATEGORY_AUDIO_ENCODER:\r
+                       return "Audio_Encoder";\r
+               case RM_CATEGORY_VIDEO_ENCODER:\r
+                       return "Video_Encoder";\r
+               case RM_CATEGORY_SCALER:\r
+                       return "Video_Scaler";\r
+               case RM_CATEGORY_TUNER:\r
+                       return "Tuner";\r
+               case RM_CATEGORY_AUDIO_MAIN_OUT:\r
+                       return "Audio_Main_Out";\r
+               case RM_CATEGORY_AUDIO_REMOTE_OUT:\r
+                       return "Audio_Remote_Out";\r
+               case RM_CATEGORY_AUDIO_SCART_OUT:\r
+                       return "Audio_Scart_Out";\r
+               case RM_CATEGORY_MM_PCM_OUT:\r
+                       return "MM_PCM_playback";\r
+               case RM_CATEGORY_AUDIO_DECODER_SUB:\r
+                       return "Audio_Decorder_Sub";\r
+               case RM_CATEGORY_JPEG_DECODER:\r
+                       return "JPEG_Decoder";\r
+               case RM_CATEGORY_MJPEG_DECODER:\r
+                       return "MJPEG_Decoder";\r
+               case RM_CATEGORY_SCALER_SUB:\r
+                       return "Video_Scaler_Sub";\r
+               case RM_CATEGORY_EXT_VIDEO_SRC:\r
+                       return "Ext_Video_Src";\r
+               case RM_CATEGORY_EXT_AUDIO_SRC:\r
+                       return "Ext_Audio_Src";\r
+               case RM_CATEGORY_EXT_HDMI_SRC:\r
+                       return "Ext_HDMI_Src";\r
+               case RM_CATEGORY_VIDEO_DECODER_SUB:\r
+                       return "Video_Decoder_Sub";\r
+               case RM_CATEGORY_CAMERA:\r
+                       return "Camera";\r
+               case RM_CATEGORY_DEMUX_REC:\r
+                       return "Demux_Rec";\r
+               case RM_CATEGORY_TUNER_SUB:\r
+                       return "Tuner_Sub";\r
+               case RM_CATEGORY_VIDEO_DECODER_UHD:\r
+                       return "Video_Decoder UHD";\r
+               case RM_CATEGORY_INPUT_SRC_DTV:\r
+                       return "Input_Src_DTV";\r
+               case RM_CATEGORY_INPUT_SRC_ATV:\r
+                       return "Input_Src_ATV";\r
+               case RM_CATEGORY_INPUT_SRC_HDMI:\r
+                       return "Input_Src_HDMI";\r
+               case RM_CATEGORY_INPUT_SRC_COMP:\r
+                       return "Input_Src_COMP";\r
+               case RM_CATEGORY_INPUT_SRC_AV:\r
+                       return "Input_Src_AV";\r
+               case RM_CATEGORY_INPUT_SRC_SCART:\r
+                       return "Input_Src_SCART";\r
+\r
+               default:\r
+                       return "";\r
+       }\r
+}\r
+\r
+int is_symlink_file(const char *path)\r
+{\r
+       struct stat st;\r
+       if (lstat(path, &st) == -1) {\r
+               RM_ERR("stat error. file path(%s)", path);\r
+               return 0;\r
+       }\r
+\r
+       return (S_ISLNK(st.st_mode)) ? 1 : 0;\r
+}\r
+// LCOV_EXCL_STOP\r
diff --git a/src/rm_module_api.cpp b/src/rm_module_api.cpp
new file mode 100644 (file)
index 0000000..8cb6d5f
--- /dev/null
@@ -0,0 +1,1260 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <assert.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <rm_internal.h>\r
+#include <rm_dbus.h>\r
+#include <rm_module_api.h>\r
+#include <rm_callback.h>\r
+#include <rm_module_api.h>\r
+#include <rm_shm_api.h>\r
+\r
+// LCOV_EXCL_START\r
+\r
+#define RMS_INITIALIZED (access("/run/rsc_mgr_ready", F_OK) == 0)\r
+\r
+void rm_wait_for_server_ready(void)\r
+{\r
+       while (!RMS_INITIALIZED) {\r
+               RM_INFO("waiting for server ready");\r
+               usleep(50*1000); // 50ms\r
+       }\r
+       RM_WARN("resource manager server is ready !!!");\r
+}\r
+\r
+int rm_get_resource_state(int rsc_id, rm_resource_state_e *state)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(state, "invalid parameter");\r
+       if (rsc_id < 0) {\r
+               RM_ERR("invalid resource id (%d)", rsc_id);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int ret = RM_OK;\r
+       int rsc_state = 0;\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("GetResourceState",\r
+                                                       g_variant_new("(i)", rsc_id),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for FindDeviceId is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       g_variant_get(result, "(i)", &rsc_state);\r
+\r
+       if (rsc_state < 0) {\r
+               RM_ERR("can't get state(%d : %d)", rsc_id, rsc_state);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       *state = (rm_resource_state_e) rsc_state;\r
+       RM_INFO("state (%d : %d)", rsc_id, rsc_state);\r
+       g_variant_unref(result);\r
+       return RM_OK;\r
+}\r
+\r
+int rm_get_scaler_state(rm_resource_list_h *list)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(list, "invalid parameter");\r
+\r
+       int ret = RM_OK;\r
+       GVariant *result = NULL;\r
+       rm_resource_list *list_reply = NULL;\r
+\r
+       list_reply = (rm_resource_list*) calloc(1, sizeof(rm_resource_list));\r
+       assert(list_reply);\r
+       list_reply->n_rsc = 0;\r
+       *list = list_reply;\r
+\r
+       ret = rm_dbus_method_call("GetScalerState",\r
+                                                       g_variant_new("(i)", RM_CATEGORY_SCALER),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for GetScalerState is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int category_id;\r
+       int cur_category_id;\r
+       int rsc_id;\r
+       int state;\r
+       int cid;\r
+       int zone_id;\r
+       int android_app;\r
+       gchar *app_id;\r
+\r
+       GVariantIter *iter;\r
+       g_variant_get(result, "(a(iiiiiisi))", &iter);\r
+\r
+       while (g_variant_iter_loop(iter, "(iiiiiisi)", &category_id, &cur_category_id, &rsc_id, &state, &cid, &zone_id, &app_id, &android_app)) {\r
+               rm_resource *resource = (rm_resource*) calloc(1, sizeof(rm_resource));\r
+               assert(resource);\r
+               resource->category_id = category_id;\r
+               resource->cur_category_id = cur_category_id;\r
+               resource->id = rsc_id;\r
+               resource->state = state;\r
+               resource->consumer_id = cid;\r
+               resource->zone_id = zone_id;\r
+               RM_INFO("(%d : %s)", resource->id, app_id ? app_id : "null");\r
+               resource->app_id = (app_id) ? (char*) strndup(app_id, strlen(app_id)) : NULL;\r
+               resource->android_app = android_app;\r
+               list_reply->rsc_list = g_list_append(list_reply->rsc_list, resource);\r
+       }\r
+       g_variant_iter_free(iter);\r
+\r
+       list_reply->n_rsc = g_list_length(list_reply->rsc_list);\r
+       list_reply->iter = list_reply->rsc_list;\r
+\r
+       g_variant_unref(result);\r
+       return ret;\r
+}\r
+\r
+int rm_get_resource_list(rm_rsc_category_e category, rm_resource_list_h *list)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(list, "invalid parameter");\r
+\r
+       int ret = RM_OK;\r
+       GVariant *result = NULL;\r
+       rm_resource_list *list_reply = NULL;\r
+\r
+       list_reply = (rm_resource_list*) calloc(1, sizeof(rm_resource_list));\r
+       assert(list_reply);\r
+       list_reply->n_rsc = 0;\r
+       *list = list_reply;\r
+\r
+       ret = rm_dbus_method_call("GetResourceList",\r
+                                                       g_variant_new("(i)", category),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for GetResourceList is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int rsc_id;\r
+       int rsc_state;\r
+       int cid;\r
+       gchar *dev_node;\r
+       gchar *app_id;\r
+\r
+       GVariantIter *iter;\r
+       g_variant_get(result, "(a(iissi))", &iter);\r
+\r
+       while (g_variant_iter_loop(iter, "(iissi)", &rsc_id, &rsc_state, &dev_node, &app_id, &cid)) {\r
+               rm_resource *resource = (rm_resource*) calloc(1, sizeof(rm_resource));\r
+               assert(resource);\r
+               resource->id = rsc_id;\r
+               resource->state = rsc_state;\r
+               resource->consumer_id = cid;\r
+               resource->support_overlay = ri_is_overlay_supported(rsc_id);\r
+               resource->max_rez = ri_get_supported_max_resolution(rsc_id);\r
+               resource->max_sampling_format = ri_get_max_sampling_format(rsc_id);\r
+               int category_id = 0;\r
+               if (ri_get_category_type_by_device_id(rsc_id, &category_id) != RI_OK) {\r
+                       RM_ERR("failed to get category of (%d)", rsc_id);\r
+               }\r
+               resource->category_id = category_id;\r
+\r
+               RM_INFO("(%d:%s)", resource->id, dev_node?dev_node : "null");\r
+               resource->node = (dev_node) ? (char*) strndup(dev_node, strlen(dev_node)) : NULL;\r
+               resource->app_id = (app_id) ? (char*) strndup(app_id, strlen(app_id)) : NULL;\r
+               list_reply->rsc_list = g_list_append(list_reply->rsc_list, resource);\r
+       }\r
+\r
+       g_variant_iter_free(iter);\r
+\r
+       list_reply->n_rsc = g_list_length(list_reply->rsc_list);\r
+       list_reply->iter = list_reply->rsc_list;\r
+\r
+       g_variant_unref(result);\r
+       return ret;\r
+}\r
+\r
+static void rm_resource_free(gpointer data)\r
+{\r
+       rm_resource *resource = (rm_resource*) data;\r
+       RM_RETURN_IF_NULL(resource, "resource null");\r
+       RM_FREE(resource->node);\r
+       RM_FREE(resource->app_id);\r
+       RM_FREE(resource);\r
+}\r
+\r
+void rm_free_resource_list(rm_resource_list_h list)\r
+{\r
+       if (!list)\r
+               return;\r
+\r
+       g_list_free_full(list->rsc_list, rm_resource_free);\r
+       RM_FREE(list);\r
+}\r
+\r
+rm_resource_h rm_resource_list_get_next(rm_resource_list_h list)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(list, "invalid list");\r
+       RM_RETURN_NULL_IF_NULL(list->rsc_list, "no device in resource list");\r
+       RM_RETURN_NULL_IF_NULL(list->iter, "no device in resource list");\r
+\r
+       GList *tmp = g_list_next(list->iter);\r
+\r
+       RM_RETURN_NULL_IF_NULL(tmp, "no next resource");\r
+\r
+       list->iter = tmp;\r
+       return (rm_resource_h) list->iter->data;\r
+}\r
+\r
+rm_resource_h rm_resource_list_get_prev(rm_resource_list_h list)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(list, "invalid list");\r
+       RM_RETURN_NULL_IF_NULL(list->rsc_list, "no device in resource list");\r
+       RM_RETURN_NULL_IF_NULL(list->iter, "no device in resource list");\r
+\r
+       GList *tmp = g_list_previous(list->iter);\r
+\r
+       RM_RETURN_NULL_IF_NULL(tmp, "no prev resource");\r
+\r
+       list->iter = tmp;\r
+       return (rm_resource_h) list->iter->data;\r
+}\r
+\r
+rm_resource_h rm_resource_list_get_first(rm_resource_list_h list)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(list, "invalid list");\r
+       RM_RETURN_NULL_IF_NULL(list->rsc_list, "no device in resource list");\r
+       RM_RETURN_NULL_IF_NULL(list->iter, "no device in resource list");\r
+\r
+       GList *tmp = g_list_first(list->iter);\r
+\r
+       RM_RETURN_NULL_IF_NULL(tmp, "no first resource");\r
+\r
+       list->iter = tmp;\r
+       return (rm_resource_h) list->iter->data;\r
+}\r
+\r
+rm_resource_h rm_resource_list_get_last(rm_resource_list_h list)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(list, "invalid list");\r
+       RM_RETURN_NULL_IF_NULL(list->rsc_list, "no device in resource list");\r
+       RM_RETURN_NULL_IF_NULL(list->iter, "no device in resource list");\r
+\r
+       GList *tmp = g_list_last(list->iter);\r
+\r
+       RM_RETURN_NULL_IF_NULL(tmp, "no last resource");\r
+\r
+       list->iter = tmp;\r
+       return (rm_resource_h) list->iter->data;\r
+}\r
+\r
+int rm_resource_list_get_count(rm_resource_list_h list)\r
+{\r
+       return (list) ? list->n_rsc : 0;\r
+}\r
+\r
+const char *rm_resource_get_node(rm_resource_h resource)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(resource, "invalid parameter");\r
+       return resource->node;\r
+}\r
+\r
+int rm_resource_get_category(rm_resource_h resource)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(resource, "invalid parameter");\r
+       return resource->category_id;\r
+}\r
+\r
+int rm_resource_get_cur_category(rm_resource_h resource)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(resource, "invalid parameter");\r
+       return resource->cur_category_id;\r
+}\r
+\r
+int rm_resource_get_consumer(rm_resource_h resource)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(resource, "invalid parameter");\r
+       return resource->consumer_id;\r
+}\r
+\r
+int rm_resource_get_state(rm_resource_h resource)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(resource, "invalid parameter");\r
+       return resource->state;\r
+}\r
+\r
+const char *rm_resource_get_app_id(rm_resource_h resource)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(resource, "invalid parameter");\r
+       return resource->app_id;\r
+}\r
+\r
+unsigned int rm_resource_get_framerate(rm_resource_h resource)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(resource, "invalid parameter");\r
+       return resource->framerate;\r
+}\r
+\r
+int rm_resource_get_id(rm_resource_h resource)\r
+{\r
+       return (resource) ? resource->id : -1;\r
+}\r
+\r
+int rm_resource_get_max_resolution(rm_resource_h resource)\r
+{\r
+       return (resource) ? resource->max_rez : -1;\r
+}\r
+\r
+bool rm_resource_support_overlay(rm_resource_h resource)\r
+{\r
+       return (resource) ? resource->support_overlay : false;\r
+}\r
+\r
+int rm_resource_get_max_sampling_format(rm_resource_h resource)\r
+{\r
+       return (resource) ? resource->max_sampling_format : -1;\r
+}\r
+\r
+int rm_resource_get_zone_id(rm_resource_h resource)\r
+{\r
+       return (resource) ? resource->zone_id : -1;\r
+}\r
+\r
+static unsigned int state_change_signal_id = 0;\r
+\r
+static void onResourceStateChanged(GDBusConnection *conn,\r
+               const gchar *sender,\r
+               const gchar *object,\r
+               const gchar *interface,\r
+               const gchar *signal,\r
+               GVariant *parameters,\r
+               gpointer user_data)\r
+{\r
+       int device_id;\r
+       int category_id;\r
+       int state;\r
+       int handle;\r
+       char *app_id;\r
+\r
+       g_variant_get(parameters, "(iiii&s)", &device_id, &category_id, &state, &handle, &app_id);\r
+       RM_INFO("signal (%s) received - (%d(%d) : %d : %d(%s))", signal, device_id, category_id, state, handle, app_id);\r
+       rm_call_state_changed_cb(category_id, device_id, state, handle, app_id);\r
+}\r
+\r
+int rm_subscribe_resource_state_change(rm_rsc_category_e category, resource_state_change_cb cb, void *data)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(cb, "invalid parameter");\r
+\r
+       if (rm_add_state_change_cb(category, cb, data) < 0) {\r
+               RM_ERR("already registered cb (%d : %p)", category, cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (state_change_signal_id)\r
+               return RM_OK;\r
+\r
+       GError *error = NULL;\r
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+       if (!connection) {\r
+               RM_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       state_change_signal_id = g_dbus_connection_signal_subscribe(connection,\r
+                       NULL,\r
+                       RM_DBUS_INTERFACE_NAME,\r
+                       "RscStateChanged",\r
+                       RM_DBUS_OBJ_PATH,\r
+                       NULL,\r
+                       G_DBUS_SIGNAL_FLAGS_NONE,\r
+                       onResourceStateChanged,\r
+                       NULL,\r
+                       NULL);\r
+\r
+       if (state_change_signal_id == 0) {\r
+               if (error) {\r
+                       RM_ERR("dbus connection close error: %s", error->message);\r
+                       g_clear_error(&error);\r
+               }\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("subscribe resource state changed (%d)", state_change_signal_id);\r
+       return RM_OK;\r
+}\r
+\r
+int rm_unsubscribe_resource_state_change(rm_rsc_category_e category, resource_state_change_cb cb)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(cb, "invalid parameter");\r
+\r
+       int remain = 0;\r
+       if ((remain = rm_remove_state_change_cb(category, cb)) < 0) {\r
+               RM_ERR("not registered cb (%d:%p)", category, cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (remain > 0) {\r
+               RM_INFO("resource state change cb(%d:%p) removed", category, cb);\r
+               return RM_OK;\r
+       }\r
+\r
+       GError *error = NULL;\r
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+       if (!connection) {\r
+               RM_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+               return RM_OK;\r
+       }\r
+\r
+       RM_INFO("remove state change signal id(%d)", state_change_signal_id);\r
+       g_dbus_connection_signal_unsubscribe(connection, state_change_signal_id);\r
+       state_change_signal_id = 0;\r
+\r
+       return RM_OK;\r
+}\r
+\r
+int rm_rsc_state_get_category(rm_resource_state_h state)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(state, "invalid state");\r
+       return state->catId;\r
+}\r
+\r
+int rm_rsc_state_get_device_id(rm_resource_state_h state)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(state, "invalid state");\r
+       return state->devId;\r
+}\r
+\r
+int rm_rsc_state_get_state(rm_resource_state_h state)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(state, "invalid state");\r
+       return state->state;\r
+}\r
+\r
+int rm_rsc_state_get_consumer_id(rm_resource_state_h state)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(state, "invalid state");\r
+       return state->consumerId;\r
+}\r
+\r
+char *rm_rsc_state_get_app_id(rm_resource_state_h state)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(state, "invalid state");\r
+       return state->appId;\r
+}\r
+\r
+static void OnResourceConflictEvent(GDBusConnection *conn,\r
+               const gchar *sender,\r
+               const gchar *object,\r
+               const gchar *interface,\r
+               const gchar *signal,\r
+               GVariant *parameters,\r
+               gpointer user_data)\r
+{\r
+       rm_conflict_resource rsc;\r
+       g_variant_get(parameters, "(iii&sii)", &rsc.catId, &rsc.devId, &rsc.cId, &rsc.appId, &rsc.aZoneId, &rsc.rZoneId);\r
+\r
+       RM_INFO("signal (%s) received - (%d:%d:%d:%s:%d:%d)", signal, rsc.catId, rsc.devId, rsc.cId, rsc.appId, rsc.aZoneId, rsc.rZoneId);\r
+\r
+       std::list<conflict_event_cb*> cb_list = rm_get_conflict_event_cb_list();\r
+\r
+       for (auto& it : cb_list) {\r
+               RM_INFO("call cb(%p)", it->cb);\r
+               it->cb(&rsc, it->data);\r
+       }\r
+}\r
+\r
+static unsigned int conflict_event_signal_id = 0;\r
+\r
+int rm_subscribe_resource_conflict_event(rm_conflict_event_cb cb, void *data)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(cb, "invalid cb");\r
+\r
+       if (rm_add_conflict_event_cb(cb, data) < 0) {\r
+               RM_ERR("already registered cb(%p)", cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (conflict_event_signal_id)\r
+               return RM_OK;\r
+\r
+       GError *error = NULL;\r
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+       if (!connection) {\r
+               RM_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+               rm_remove_conflict_event_cb(cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       conflict_event_signal_id = g_dbus_connection_signal_subscribe(connection,\r
+                       NULL,\r
+                       RM_DBUS_INTERFACE_NAME,\r
+                       "RscConflicted",\r
+                       RM_DBUS_OBJ_PATH,\r
+                       NULL,\r
+                       G_DBUS_SIGNAL_FLAGS_NONE,\r
+                       OnResourceConflictEvent,\r
+                       NULL,\r
+                       NULL);\r
+\r
+       if (conflict_event_signal_id == 0) {\r
+               if (error) {\r
+                       RM_ERR("dbus connection close error: %s", error->message);\r
+                       g_clear_error(&error);\r
+                       rm_remove_conflict_event_cb(cb);\r
+               }\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("subscribe conflict event (%d)", conflict_event_signal_id);\r
+\r
+       return RM_OK;\r
+}\r
+\r
+int rm_unsubscribe_resource_conflict_event(rm_conflict_event_cb cb)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(cb, "invalid cb");\r
+\r
+       int remain = 0;\r
+       if ((remain = rm_remove_conflict_event_cb(cb)) < 0) {\r
+               RM_ERR("unregistered cb(%p)", cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("callback unregistered(%p)-(%d)", cb, remain);\r
+\r
+       if (remain > 0)\r
+               return RM_OK;\r
+\r
+       GError *error = NULL;\r
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+       if (!connection) {\r
+               RM_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+               return RM_OK;\r
+       }\r
+\r
+       RM_INFO("remove conflict event signal id(%d)", conflict_event_signal_id);\r
+       g_dbus_connection_signal_unsubscribe(connection, conflict_event_signal_id);\r
+       conflict_event_signal_id = 0;\r
+\r
+       return RM_OK;\r
+}\r
+\r
+int rm_conflict_get_category_id(rm_conflict_resource_h rsc)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(rsc, "invalid rsc");\r
+       return rsc->catId;\r
+}\r
+\r
+int rm_conflict_get_device_id(rm_conflict_resource_h rsc)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(rsc, "invalid rsc");\r
+       return rsc->devId;\r
+}\r
+\r
+int rm_conflict_get_consumer_id(rm_conflict_resource_h rsc)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(rsc, "invalid rsc");\r
+       return rsc->cId;\r
+}\r
+\r
+const char *rm_conflict_get_app_id(rm_conflict_resource_h rsc)\r
+{\r
+       RM_RETURN_NULL_IF_NULL(rsc, "invalid rsc");\r
+       return rsc->appId;\r
+}\r
+\r
+int rm_conflict_get_multiview_zone_id_consumer(rm_conflict_resource_h rsc)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(rsc, "invalid rsc");\r
+       return rsc->aZoneId;\r
+}\r
+\r
+int rm_conflict_get_multiview_zone_id_requester(rm_conflict_resource_h rsc)\r
+{\r
+       RM_RETURN_MINUS_IF_NULL(rsc, "invalid rsc");\r
+       return rsc->rZoneId;\r
+}\r
+\r
+int rm_get_resource_collection_state(rm_rsc_collection_e collection, rm_resource_list_h *list)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(list, "invalid parameter");\r
+\r
+       int ret;\r
+       GVariant *result = NULL;\r
+       rm_resource_list *list_reply = NULL;\r
+\r
+       list_reply = (rm_resource_list*) calloc(1, sizeof(rm_resource_list));\r
+       assert(list_reply);\r
+       list_reply->n_rsc = 0;\r
+       *list = list_reply;\r
+\r
+       ret = rm_dbus_method_call("GetRscCollectionState",\r
+                                                       g_variant_new("(i)", collection),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for GetRscCollectionState is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int rsc_id;\r
+       int rsc_state;\r
+       int rsc_category;\r
+       int cid;\r
+       int zone_id;\r
+       int android_app;\r
+       gchar *app_id;\r
+       gchar *dev_node;\r
+\r
+       GVariantIter *iter;\r
+       g_variant_get(result, "(a(isiiisii))", &iter);\r
+\r
+       while (g_variant_iter_loop(iter, "(isiiisii)", &rsc_id, &dev_node, &rsc_state, &rsc_category, &cid, &app_id, &zone_id, &android_app)) {\r
+               rm_resource *resource = (rm_resource*) calloc(1, sizeof(rm_resource));\r
+               assert(resource);\r
+               resource->id = rsc_id;\r
+               RM_INFO("(%d:%s)", resource->id, dev_node?dev_node : "null");\r
+               resource->node = (dev_node) ? (char*) strndup(dev_node, strlen(dev_node)) : NULL;\r
+               resource->state = rsc_state;\r
+               resource->category_id = rsc_category;\r
+               resource->framerate = ri_get_video_category_framerate(rsc_category);\r
+               resource->consumer_id = cid;\r
+               resource->app_id = (app_id) ? (char*) strndup(app_id, strlen(app_id)) : NULL;\r
+               resource->zone_id = zone_id;\r
+               resource->android_app = android_app;\r
+               list_reply->rsc_list = g_list_append(list_reply->rsc_list, resource);\r
+       }\r
+\r
+       g_variant_iter_free(iter);\r
+\r
+       list_reply->n_rsc = g_list_length(list_reply->rsc_list);\r
+       list_reply->iter = list_reply->rsc_list;\r
+\r
+       g_variant_unref(result);\r
+       return ret;\r
+}\r
+\r
+int rm_unmask_category_options(int category)\r
+{\r
+       int result = category;\r
+\r
+       result = (result & ~RM_DEVICE_OPT_MAIN);\r
+       result = (result & ~RM_DEVICE_OPT_SUB);\r
+\r
+       return ri_unmask_category_options(result);\r
+}\r
+\r
+int rm_find_device_id(int virtual_id)\r
+{\r
+       if (virtual_id < 0) {\r
+               RM_ERR("invalid resource id (%d)", virtual_id);\r
+               return -1;\r
+       }\r
+\r
+       int real_id = 0;\r
+       if (rm_shm_find_device_id(virtual_id, &real_id) == RM_OK) {\r
+               RM_INFO("real id (%d:%d)", virtual_id, real_id);\r
+               return real_id;\r
+       }\r
+\r
+       int ret = RM_OK;\r
+\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("FindDeviceId",\r
+                                               g_variant_new("(i)", virtual_id),\r
+                                               &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for FindDeviceId is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       g_variant_get(result, "(i)", &real_id);\r
+\r
+       RM_INFO("real id (%d:%d)", virtual_id, real_id);\r
+\r
+       g_variant_unref(result);\r
+       return real_id;\r
+}\r
+\r
+int rm_swap_resources(int device_id_a, int device_id_b)\r
+{\r
+       if ((device_id_a < 0) || (device_id_b < 0)) {\r
+               RM_ERR("invalid resource id (%d/%d)", device_id_a, device_id_b);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int ret = RM_OK;\r
+       int swap_result = 0;\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("SwapResources",\r
+                                               g_variant_new("(ii)", device_id_a, device_id_b),\r
+                                               &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for SwapResources is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       g_variant_get(result, "(i)", &swap_result);\r
+\r
+       if (swap_result < 0) {\r
+               RM_ERR("faild to swap resources(%d:%d)", device_id_a, device_id_b);\r
+               ret = RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("swapped (%d:%d)", device_id_a, device_id_b);\r
+\r
+       g_variant_unref(result);\r
+       return ret;\r
+}\r
+\r
+int rm_swap_resources_async(int device_id_a, int device_id_b)\r
+{\r
+       if ((device_id_a < 0) || (device_id_b < 0)) {\r
+               RM_ERR("invalid resource id (%d/%d)", device_id_a, device_id_b);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int ret = rm_dbus_method_call_async_with_no_reply("SwapResources",\r
+                                                       g_variant_new("(ii)", device_id_a, device_id_b));\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for SwapResourcesAsync is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("swapped requested (%d:%d)", device_id_a, device_id_b);\r
+       return RM_OK;\r
+}\r
+\r
+int rm_restore_resources(int category)\r
+{\r
+       if (category < 0) {\r
+               RM_ERR("invalid category id (%d)", category);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int ret = RM_OK;\r
+       int restore_result = 0;\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("RestoreResources",\r
+                                                       g_variant_new("(i)", category),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for RestoreResources is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       g_variant_get(result, "(i)", &restore_result);\r
+\r
+       if (restore_result < 0) {\r
+               RM_ERR("faild to restore resources(%d)", category);\r
+               ret = RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("restored (%d)", category);\r
+\r
+       g_variant_unref(result);\r
+       return ret;\r
+}\r
+\r
+int rm_get_app_id(int handle, char**app_id)\r
+{\r
+       if (handle < 0 || !app_id) {\r
+               RM_ERR("invalid param (%d)", handle);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (rm_shm_get_app_id(handle, app_id) == RM_OK)\r
+               return RM_OK;\r
+\r
+       int ret = RM_OK;\r
+       int dbus_ret = 0;\r
+       char *ret_val = NULL;\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("GetAppId",\r
+                                                       g_variant_new("(i)", handle),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for GetAppId is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       g_variant_get(result, "(i&s)", &dbus_ret, &ret_val);\r
+\r
+       if (dbus_ret < 0)\r
+               ret = RM_ERROR;\r
+\r
+       if (ret_val)\r
+               *app_id = strndup(ret_val, strlen(ret_val));\r
+\r
+       RM_INFO("(%d) - app_id(%d : %s)", dbus_ret, handle, (ret_val) ? *app_id : "null");\r
+\r
+       g_variant_unref(result);\r
+       return ret;\r
+}\r
+\r
+int rm_get_active_audio_out(int handle)\r
+{\r
+       if (handle < 0) {\r
+               RM_ERR("invalid handle(%d)", handle);\r
+               return -1;\r
+       }\r
+\r
+       int active_audio_out = 0;\r
+       if (rm_shm_get_active_audio_out(handle, &active_audio_out) == RM_OK)\r
+               return active_audio_out;\r
+\r
+       int ret = 0;\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("GetActiveAudioOut",\r
+                                                       g_variant_new("(i)", handle),\r
+                                                       &result);\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for GetActiveAudioOut is failed");\r
+               return -1;\r
+       }\r
+\r
+       g_variant_get(result, "(i)", &active_audio_out);\r
+\r
+       RM_INFO("active audio out (%d:%d)", handle, active_audio_out);\r
+\r
+       g_variant_unref(result);\r
+       return active_audio_out;\r
+}\r
+\r
+int rm_scaler_get_virtual_id(rm_resource_h scaler)\r
+{\r
+       return (scaler) ? scaler->virtual_id : -1;\r
+}\r
+\r
+int rm_scaler_get_source_id(rm_resource_h scaler)\r
+{\r
+       return (scaler) ? scaler->source_id : -1;\r
+}\r
+\r
+static unsigned int scaler_change_signal_id = 0;\r
+static void onScalerStateChanged(GDBusConnection *conn,\r
+               const gchar *sender,\r
+               const gchar *object,\r
+               const gchar *interface,\r
+               const gchar *signal,\r
+               GVariant *param,\r
+               gpointer user_data)\r
+{\r
+       rm_resource_list *scaler_list = NULL;\r
+\r
+       scaler_list = (rm_resource_list*) calloc(1, sizeof(rm_resource_list));\r
+       assert(scaler_list);\r
+       scaler_list->n_rsc = 0;\r
+\r
+       int virtual_id;\r
+       int source_id;\r
+       GVariantIter *iter;\r
+       g_variant_get(param, "(a(ii))", &iter);\r
+\r
+       RM_INFO(">> scaler state changed");\r
+       while (g_variant_iter_loop(iter, "(ii)", &virtual_id, &source_id)) {\r
+               rm_resource *scaler = (rm_resource*) calloc(1, sizeof(rm_resource));\r
+               assert(scaler);\r
+\r
+               scaler->virtual_id = virtual_id;\r
+               scaler->source_id = source_id;\r
+               RM_INFO("(%d:%d)", scaler->virtual_id, scaler->source_id);\r
+\r
+               scaler_list->rsc_list = g_list_append(scaler_list->rsc_list, scaler);\r
+       }\r
+\r
+       g_variant_iter_free(iter);\r
+\r
+       scaler_list->n_rsc = g_list_length(scaler_list->rsc_list);\r
+       scaler_list->iter = scaler_list->rsc_list;\r
+\r
+       rm_call_scaler_state_changed_cb(scaler_list);\r
+\r
+       g_list_free_full(scaler_list->rsc_list, rm_resource_free);\r
+       RM_FREE(scaler_list);\r
+}\r
+\r
+int rm_subscribe_scaler_state_change(scaler_state_change_cb cb, void *data)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(cb, "invalid parameter");\r
+\r
+       if (rm_add_scaler_state_change_cb(cb, data) < 0) {\r
+               RM_ERR("already registered cb (%p)", cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (scaler_change_signal_id)\r
+               return RM_OK;\r
+\r
+       GError *error = NULL;\r
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+       if (!connection) {\r
+               RM_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       scaler_change_signal_id = g_dbus_connection_signal_subscribe(connection,\r
+                       NULL,\r
+                       RM_DBUS_INTERFACE_NAME,\r
+                       "ScalerStateChanged",\r
+                       RM_DBUS_OBJ_PATH,\r
+                       NULL,\r
+                       G_DBUS_SIGNAL_FLAGS_NONE,\r
+                       onScalerStateChanged,\r
+                       NULL,\r
+                       NULL);\r
+\r
+       if (scaler_change_signal_id == 0) {\r
+               if (error) {\r
+                       RM_ERR("dbus connection close error: %s", error->message);\r
+                       g_clear_error(&error);\r
+               }\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("subscribe resource state changed (%d)", scaler_change_signal_id);\r
+       return RM_OK;\r
+}\r
+\r
+int rm_unsubscribe_scaler_state_change(scaler_state_change_cb cb)\r
+{\r
+       RM_RETURN_ERR_IF_NULL(cb, "invalid parameter");\r
+\r
+       int remain = 0;\r
+       if ((remain = rm_remove_scaler_state_change_cb(cb)) < 0) {\r
+               RM_ERR("not registered cb (%p)", cb);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (remain > 0) {\r
+               RM_INFO("scaler state change cb(%p) removed", cb);\r
+               return RM_OK;\r
+       }\r
+\r
+       GError *error = NULL;\r
+       GDBusConnection *connection = g_bus_get_sync(G_BUS_TYPE_SYSTEM, NULL, &error);\r
+       if (!connection) {\r
+               RM_ERR("failed to get connection (%s)", (error) ? error->message : "unknown");\r
+               return RM_OK;\r
+       }\r
+\r
+       RM_INFO("remove scaler change signal id(%d)", scaler_change_signal_id);\r
+       g_dbus_connection_signal_unsubscribe(connection, scaler_change_signal_id);\r
+       scaler_change_signal_id = 0;\r
+\r
+       return RM_OK;\r
+}\r
+\r
+int rm_get_scaler_hw_id(int zone_id, int *id)\r
+{\r
+       if (zone_id <= 0) {\r
+               RM_ERR("invalid resource id (%d)", zone_id);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (rm_shm_find_scaler_hw_id(zone_id, id) == RM_OK)\r
+               return RM_OK;\r
+\r
+       int ret = RM_OK;\r
+       int hw_id = 0;\r
+       GVariant *result = NULL;\r
+\r
+       ret = rm_dbus_method_call("GetScalerHWID",\r
+                                                       g_variant_new("(i)", zone_id),\r
+                                                       &result);\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for GetScalerHWID is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       g_variant_get(result, "(i)", &hw_id);\r
+\r
+       if (hw_id < 0) {\r
+               RM_ERR("can't get hw id(%d:%d)", zone_id, hw_id);\r
+               g_variant_unref(result);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       *id = hw_id;\r
+       RM_INFO("hw id (%d:%d)", zone_id, hw_id);\r
+       g_variant_unref(result);\r
+       return RM_OK;\r
+}\r
+\r
+int rm_notify_resource_policy(int policy)\r
+{\r
+       if (policy < 0) {\r
+               RM_ERR("invalid policy (%d)", policy);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int ret = rm_dbus_method_call_async_with_no_reply("NotifyResourcePolicy",\r
+                                                       g_variant_new("(i)", policy));\r
+\r
+       if (ret) {\r
+               RM_ERR("dbus_method_call() for NotifyResourcePolicy is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("notified (%d)", policy);\r
+       return ret;\r
+}\r
+\r
+int rm_notify_app_zone_info_async(const char *app_id, int zone_id)\r
+{\r
+       if (!app_id || zone_id < -1) {\r
+               RM_ERR("invalid param (%d)", zone_id);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       if (rm_dbus_method_call_async_with_no_reply("NotifyAppZoneInfo", g_variant_new("(si)", app_id, zone_id)) != 0) {\r
+               RM_ERR("dbus_method_call() for NotifyAppZoneInfo is failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("notified (%s:%d)", app_id, zone_id);\r
+       return RM_OK;\r
+}\r
+\r
+int rm_reclaim_resources(int handle)\r
+{\r
+       RM_INFO("reclaim resources of (%d)", handle);\r
+\r
+       if (rm_dbus_method_call_async_with_no_reply("ReclaimResources", g_variant_new("(i)", handle)) != 0) {\r
+               RM_ERR("dbus call for ReclaimResources failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       return RM_OK;\r
+}\r
+\r
+int rm_reclaim_app_resources(const char *app_id, const bool notify)\r
+{\r
+       if (!app_id) {\r
+               RM_ERR("invalid app id");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("reclaim resources of (%s:%d)", app_id, notify);\r
+\r
+       GVariant *response = NULL;\r
+       if (rm_dbus_method_call("ReclaimAppResources", g_variant_new("(si)", app_id, notify), &response) != 0) {\r
+               RM_ERR("dbus call for ReclaimAppResources failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int reclaim_result = 0;\r
+       g_variant_get(response, "(i)", &reclaim_result);\r
+\r
+       int result = (reclaim_result < 0) ? RM_ERROR : RM_OK;\r
+       RM_INFO("reclaime result (%s : %d)", app_id, result);\r
+\r
+       g_variant_unref(response);\r
+       return result;\r
+}\r
+\r
+int rm_reclaim_app_resources_async(const char *app_id, const bool notify)\r
+{\r
+       if (!app_id) {\r
+               RM_ERR("invalid app id");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("reclaim resources of (%s : %d)", app_id, notify);\r
+\r
+       if (rm_dbus_method_call_async_with_no_reply("ReclaimAppResources", g_variant_new("(si)", app_id, notify)) != 0) {\r
+               RM_ERR("dbus call for ReclaimAppResources failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       return RM_OK;\r
+}\r
+\r
+rm_resource_list_h rm_resource_list_create(void)\r
+{\r
+       rm_resource_list *list = (rm_resource_list*) calloc(1, sizeof(rm_resource_list));\r
+       if (!list) {\r
+               RM_ERR("insufficient memory");\r
+               return NULL;\r
+       }\r
+\r
+       list->n_rsc = 0;\r
+       return list;\r
+}\r
+\r
+int rm_resource_list_append(rm_resource_list_h list, const rm_resource_h resource)\r
+{\r
+       if (!list || !resource) {\r
+               RM_ERR("invalid param");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       list->rsc_list = g_list_append(list->rsc_list, resource);\r
+       list->n_rsc = g_list_length(list->rsc_list);\r
+       list->iter = list->rsc_list;\r
+       return RM_OK;\r
+}\r
+\r
+rm_resource_h rm_create_video_encoder(const unsigned int width, const unsigned int height, const unsigned int framerate)\r
+{\r
+       rm_resource *resource = (rm_resource*) calloc(1, sizeof(rm_resource));\r
+       if (!resource) {\r
+               RM_ERR("insufficient memory");\r
+               return NULL;\r
+       }\r
+\r
+       resource->width = width;\r
+       resource->height = height;\r
+       resource->framerate = framerate;\r
+       return resource;\r
+}\r
+\r
+int rm_allocatable_video_encoders(const rm_resource_list_h list, bool *result)\r
+{\r
+       if (!list) {\r
+               RM_ERR("invalid param");\r
+               *result = false;\r
+               return RM_ERROR;\r
+       }\r
+\r
+       GVariantBuilder builder;\r
+       g_variant_builder_init(&builder, G_VARIANT_TYPE("(a(uuu))"));\r
+       g_variant_builder_open(&builder, G_VARIANT_TYPE("a(uuu)"));\r
+\r
+       rm_resource_h resource = rm_resource_list_get_first(list);\r
+       while (resource) {\r
+               RM_INFO("w(%u)/h(%u)/fps(%u)", rm_resource_get_width(resource), rm_resource_get_height(resource), rm_resource_get_framerate(resource));\r
+               g_variant_builder_add(&builder, "(uuu)", rm_resource_get_width(resource), rm_resource_get_height(resource), rm_resource_get_framerate(resource));\r
+               resource = rm_resource_list_get_next(list);\r
+       };\r
+\r
+       g_variant_builder_close(&builder);\r
+\r
+       GVariant *response = NULL;\r
+       if (rm_dbus_method_call("AllocatableVideoEncoders", g_variant_builder_end(&builder), &response) != 0) {\r
+               *result = false;\r
+               RM_ERR("dbus_method_call() for AllocatableVideoEncoders failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int available = 0;\r
+       g_variant_get(response, "(i)", &available);\r
+       g_variant_unref(response);\r
+       RM_INFO("available (%d)", available);\r
+       *result = (available == 1);\r
+       return RM_OK;\r
+}\r
+\r
+unsigned int rm_resource_get_width(const rm_resource_h resource)\r
+{\r
+       if (!resource) {\r
+               RM_ERR("invalid param");\r
+               return 0;\r
+       }\r
+       return resource->width;\r
+}\r
+\r
+unsigned int rm_resource_get_height(const rm_resource_h resource)\r
+{\r
+       if (!resource) {\r
+               RM_ERR("invalid param");\r
+               return 0;\r
+       }\r
+       return resource->height;\r
+}\r
+\r
+bool rm_resource_android_app(const rm_resource_h resource)\r
+{\r
+       if (!resource)\r
+               return false;\r
+\r
+       return resource->android_app;\r
+}\r
+\r
+int rm_reclaim_video_decoders(const char *requester)\r
+{\r
+       if (!requester) {\r
+               RM_ERR("invalid param");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("reclaim video decoders allocated to other than (%s)", requester);\r
+\r
+       GVariant *response = NULL;\r
+       if (rm_dbus_method_call("ReclaimVideoDecoders", g_variant_new("(s)", requester), &response) != 0) {\r
+               RM_ERR("dbus call for ReclaimVideoDecoders failed");\r
+               return RM_ERROR;\r
+       }\r
+\r
+       int result = 0;\r
+       g_variant_get(response, "(i)", &result);\r
+       g_variant_unref(response);\r
+\r
+       RM_INFO("result : (%d)", result);\r
+       return (result == 0) ? RM_OK : RM_ERROR;\r
+}\r
+\r
+bool rm_active_player(const int handle)\r
+{\r
+       bool result = false;\r
+       if (rm_shm_active_player(handle, &result) == RM_OK) {\r
+               RM_INFO("(%d : %d)", handle, result);\r
+               return result;\r
+       }\r
+\r
+       GVariant *response = NULL;\r
+       if (rm_dbus_method_call("ActivePlayer", g_variant_new("(i)", handle), &response) != 0) {\r
+               RM_ERR("dbus call for ActivePlayer (%d) failed", handle);\r
+               return false;\r
+       }\r
+\r
+       g_variant_get(response, "(b)", &result);\r
+\r
+       RM_INFO("(%d : %d)", handle, result);\r
+       return result;\r
+}\r
+\r
+bool rm_reclaimed_player(const int handle)\r
+{\r
+       bool result = false;\r
+\r
+       GVariant *response = NULL;\r
+       if (rm_dbus_method_call("ReclaimedPlayer", g_variant_new("(i)", handle), &response)!= 0) {\r
+               RM_ERR("dbus call for ReclaimedPlayer (%d) failed", handle);\r
+               return false;\r
+       }\r
+\r
+       g_variant_get(response, "(b)", &result);\r
+\r
+       RM_INFO("(%d : %d)", handle, result);\r
+       return result;\r
+}\r
+\r
+// LCOV_EXCL_STOP\r
diff --git a/src/rm_msg.cpp b/src/rm_msg.cpp
new file mode 100644 (file)
index 0000000..f1f6ae4
--- /dev/null
@@ -0,0 +1,211 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <stdlib.h>\r
+#include <sys/types.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+#include <errno.h>\r
+#include <unistd.h>\r
+#include <time.h>\r
+\r
+#include <rm_msg.h>\r
+#include <rm_internal.h>\r
+#include <rm_debug.h>\r
+\r
+#define RM_MSGQ_KEY_TX 8211\r
+#define RM_MSGQ_KEY_RX 8212\r
+\r
+static int msgq_tx = -1;\r
+static int msgq_rx = -1;\r
+\r
+static inline bool msgq_initialized(void)\r
+{\r
+       return ((msgq_tx >= 0) && (msgq_rx >= 0));\r
+}\r
+\r
+static int msgq_create(void)\r
+{\r
+       msgq_tx = msgget((key_t)RM_MSGQ_KEY_TX, 0666 | IPC_CREAT);\r
+       msgq_rx = msgget((key_t)RM_MSGQ_KEY_RX, 0666 | IPC_CREAT);\r
+\r
+       if ((msgq_tx == -1) || (msgq_rx == -1)) {\r
+               RM_ERR("failed to get msgq_id - msgq_tx(%d), msgq_rx(%d)", msgq_tx, msgq_rx);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_INFO("msgq_tx (%d), msgq_rx(%d)", msgq_tx, msgq_rx);\r
+\r
+       return RM_OK;\r
+}\r
+\r
+// LCOV_EXCL_START\r
+static int msgq_recover_tx(void)\r
+{\r
+       msgq_tx = msgget((key_t)RM_MSGQ_KEY_TX, 0666 | IPC_CREAT);\r
+\r
+       if (msgq_tx == -1) {\r
+               RM_ERR("failed to get new msgq_id - msgq_tx(%d), errno(%d)", msgq_tx, errno);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_ERR("msgq recovered - msgq_tx(%d)", msgq_tx);\r
+       return RM_OK;\r
+}\r
+\r
+\r
+static int msgq_recover_rx(void)\r
+{\r
+       msgq_rx = msgget((key_t)RM_MSGQ_KEY_RX, 0666 | IPC_CREAT);\r
+\r
+       if (msgq_rx == -1) {\r
+               RM_ERR("failed to get new msgq_id - msgq_rx(%d), errno(%d)", msgq_rx, errno);\r
+               return RM_ERROR;\r
+       }\r
+\r
+       RM_ERR("msgq recovered - msgq_rx(%d)", msgq_rx);\r
+       return RM_OK;\r
+}\r
+// LCOV_EXCL_STOP\r
+\r
+int rm_send_msg(rm_msg_request *data)\r
+{\r
+       struct timespec tnow;\r
+       clock_gettime(CLOCK_MONOTONIC, &tnow);\r
+\r
+       if (!msgq_initialized())\r
+               msgq_create();\r
+\r
+       RM_INFO("msgq_tx %d msgq_rx %d", msgq_tx, msgq_rx);\r
+\r
+       int retry = 0;\r
+\r
+       RM_WARN("handle(%d) req.data_type : %ld, req #%d, req.type : %d, req.pid : %d", data->handle, data->data_type, data->request_num, data->type, data->pid);\r
+\r
+       while (msgsnd(msgq_tx,(void*) data, sizeof(rm_msg_request) - sizeof(long), 0) == -1) {\r
+               // LCOV_EXCL_START\r
+               RM_ERR("failed to send message (%d)", errno);\r
+\r
+               if (errno == EIDRM) {\r
+                       RM_ERR("ERROR! msgid removed from system");\r
+                       if (msgq_recover_tx() != RM_OK)\r
+                               return RM_ERROR;\r
+               } else if ((errno == EINVAL) && (data->data_type > 0)) { /* maybe msgid removed from system */\r
+                       RM_ERR("ERROR! invalid argument error. maybe msgid removed from system");\r
+                       if (msgq_recover_tx() != RM_OK)\r
+                               return RM_ERROR;\r
+               }\r
+\r
+               if (retry >= 5) {\r
+                       RM_ERR("ERROR! timeout");\r
+                       return RM_ERROR;\r
+               }\r
+\r
+               usleep(20 * 1000); /* 20ms */\r
+               retry++;\r
+               // LCOV_EXCL_STOP\r
+       }\r
+\r
+       return RM_OK;\r
+}\r
+\r
+int rm_receive_msg(rm_msg_response *response, int msg_type)\r
+{\r
+       int retry = 0;\r
+       struct timespec tnow;\r
+       clock_gettime(CLOCK_MONOTONIC, &tnow);\r
+\r
+       if (!msgq_initialized())\r
+               msgq_create();\r
+\r
+       while (msgrcv(msgq_rx, (void*) response, sizeof(rm_msg_response) - sizeof(long), msg_type, 0) == -1) {\r
+               // LCOV_EXCL_START\r
+               RM_ERR("Failed to get message, errno(%d)", errno);\r
+\r
+               if (errno == EIDRM) {\r
+                       RM_ERR("WARNING! msgid removed from system");\r
+                       msgq_recover_rx();\r
+                       return RM_ERROR;\r
+               } else if (errno == EINVAL) { /* maybe msgid removed from system */\r
+                       RM_ERR("ERROR! invalid argument error. maybe msgid removed from system");\r
+                       if (msgq_recover_rx() != RM_OK)\r
+                               return RM_ERROR;\r
+\r
+                       if (retry >= 5) {\r
+                               RM_ERR("ERROR! timeout");\r
+                               return RM_ERROR;\r
+                       }\r
+\r
+                       usleep(20 * 1000); /* 20ms */\r
+                       retry++;\r
+               } else if (errno == EINTR) {\r
+                       RM_ERR("WARNING! System Call Inturrupted");\r
+                       continue;\r
+               } else {\r
+                       RM_ERR("Error(errno:%d) is occured!!", errno);\r
+                       return RM_ERROR;\r
+               }\r
+               // LCOV_EXCL_STOP\r
+       }\r
+\r
+       return RM_OK;\r
+}\r
+\r
+static int get_msg_uid(void)\r
+{\r
+       static int msg_id = 1;\r
+       const int msg_id_max = 65535; // (2^16 - 1)\r
+\r
+       return (++msg_id > msg_id_max) ? 1 : msg_id;\r
+}\r
+\r
+long get_data_type(int handle, int msg_type)\r
+{\r
+       long data_type = 0L;\r
+       int msg_uid = get_msg_uid();\r
+\r
+       data_type = ((static_cast<long>(handle)) << 22);\r
+       data_type |= ((static_cast<long>(msg_type)) << 16);\r
+       data_type |= msg_uid;\r
+       data_type = (data_type < 0) ? labs(data_type) : data_type; /* message type must be > 0, refer to description of struct msgbuf */\r
+\r
+       RM_INFO("data_type : (%ld), msg_uid : (%d), handle : (%d), msg_type : (%d)", data_type, msg_uid, handle, msg_type);\r
+\r
+       return data_type;\r
+}\r
+\r
+unsigned long long get_uptime(void)\r
+{\r
+       struct timespec t;\r
+       clock_gettime(CLOCK_MONOTONIC, &t);\r
+       return t.tv_sec;\r
+}\r
+\r
+void rm_construct_request_msg(rm_msg_request *request, int msg_type, int handle)\r
+{\r
+       if (!request) {\r
+               RM_ERR("request is NULL");\r
+               return;\r
+       }\r
+\r
+       request->data_type = (msg_type == RM_REQUEST_REGISTER) ? (RM_REQUEST_DATA_TYPE_REGISTER | getpid()) : get_data_type(handle, msg_type);\r
+       request->type = msg_type;\r
+       request->handle = handle;\r
+       request->pid = getpid();\r
+       request->time = get_uptime();\r
+\r
+       RM_INFO("DONE");\r
+}\r
diff --git a/src/rm_shm_api.cpp b/src/rm_shm_api.cpp
new file mode 100644 (file)
index 0000000..8686641
--- /dev/null
@@ -0,0 +1,84 @@
+/*
+ * 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.
+ */
+
+#include <rm_internal.h>
+#include <rm_debug.h>
+#include <RMShmCache.h>
+
+// LCOV_EXCL_START
+
+int rm_shm_get_app_id(const int handle, char** app_id)
+{
+       if (handle < 0 || !app_id) {
+               RM_ERR("invalid param (%d)", handle);
+               return RM_ERROR;
+       }
+
+       *app_id = RMShmCache::GetInstance()->GetAppId(handle);
+       return (*app_id == nullptr) ? RM_ERROR : RM_OK;
+}
+
+int rm_shm_find_scaler_hw_id(const int zone_id, int *hw_id)
+{
+       if (zone_id < 0 || !hw_id) {
+               RM_ERR("invalid param (%d)", zone_id);
+               return RM_ERROR;
+       }
+
+       return RMShmCache::GetInstance()->FindScalerHWID(zone_id, hw_id);
+}
+
+int rm_shm_find_device_id(const int virtual_id, int *device_id)
+{
+       if (!device_id) {
+               RM_ERR("invalid param (%d)", virtual_id);
+               return RM_ERROR;
+       }
+
+       return RMShmCache::GetInstance()->FindScalerDeviceID(virtual_id, device_id);
+}
+
+int rm_shm_find_players_using_audio_main_out(rm_resource_list_h *list)
+{
+       if (!list) {
+               RM_ERR("invalid param");
+               return RM_ERROR;
+       }
+
+       return RMShmCache::GetInstance()->FindPlayersUsingAudioMainOut(list);
+}
+
+int rm_shm_get_active_audio_out(const int handle, int *audio_out)
+{
+       if (handle < 0 || !audio_out) {
+               RM_ERR("invalid param (%d)", handle);
+               return RM_ERROR;
+       }
+
+       return RMShmCache::GetInstance()->GetActiveAudioOut(handle, audio_out);
+}
+
+int rm_shm_active_player(const int handle, bool *result)
+{
+       if (handle < 0 || !result) {
+               RM_ERR("invalid param (%d)", handle);
+               return false;
+       }
+
+       return RMShmCache::GetInstance()->ActivePlayer(handle, result);
+}
+
+// LCOV_EXCL_STOP
diff --git a/ut/CMakeLists.txt b/ut/CMakeLists.txt
new file mode 100644 (file)
index 0000000..c4e2cd9
--- /dev/null
@@ -0,0 +1,44 @@
+INCLUDE(FindPkgConfig)
+pkg_check_modules(PKGS REQUIRED
+    resource-information
+    dlog
+    glib-2.0
+    gtest
+    gmock
+)
+
+FOREACH(inc ${PKGS_INCLUDE_DIRS})
+    INCLUDE_DIRECTORIES(${inc})
+ENDFOREACH(inc)
+
+FOREACH (flag ${PKGS_CXXFLAGS})
+    SET(EXTRA_CXXFLAGS "${EXTRA_CXXFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+IF(NOT DEFINED CHIP_NAME)
+       SET(CHIP_NAME CHIP_PONTUSM)
+ENDIF(NOT DEFINED CHIP_NAME)
+
+SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${EXTRA_CXXFLAGS}")
+
+SET(INCLUDE_DIR_TO_TEST ${CMAKE_CURRENT_SOURCE_DIR}/../include ${CMAKE_CURRENT_SOURCE_DIR}/testcase)
+
+SET(SRC_TESTCASE
+    ${CMAKE_CURRENT_SOURCE_DIR}/testcase/common.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/testcase/TCPlayer.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/testcase/TCResource.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/testcase/TCCallbackListener.cpp
+    ${CMAKE_CURRENT_SOURCE_DIR}/testcase/ut_main.cpp
+)
+
+ADD_EXECUTABLE(${RSCMGRPKGNAME} ${SRC_TESTCASE})
+
+INCLUDE_DIRECTORIES(${INCLUDE_DIR_GTEST} ${INCLUDE_DIR_TO_TEST})
+#FIND_PACKAGE(Threads REQUIRED)
+
+MESSAGE("PKGS_LDFLAGS : "${PKGS_LDFLAGS})
+TARGET_LINK_LIBRARIES(${RSCMGRPKGNAME} ${CMAKE_THREAD_LIBS_INIT} ${PKGS_LDFLAGS} ${PROJECT_NAME} -lpthread)
+
+MESSAGE("INSTALL DIR :" ${BINDIR})
+
+INSTALL(TARGETS ${RSCMGRPKGNAME} DESTINATION ${BINDIR})
diff --git a/ut/TCList.dat.in b/ut/TCList.dat.in
new file mode 100644 (file)
index 0000000..f90bfd5
--- /dev/null
@@ -0,0 +1 @@
+rscmgr_hawkp_atsc.xml
diff --git a/ut/testcase/TCCallbackListener.cpp b/ut/testcase/TCCallbackListener.cpp
new file mode 100644 (file)
index 0000000..713b85a
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include <assert.h>\r
+#include <rm_module_api.h>\r
+\r
+#include <ut_common.h>\r
+#include <TCCallbackListener.h>\r
+\r
+void TCCallbackListener::ScalerStateChangeCb(rm_resource_list_h scalers, void *data)\r
+{\r
+       TCCallbackListener *listener = (TCCallbackListener*) data;\r
+       assert(listener);\r
+\r
+       listener->RemoveAllScalers();\r
+       listener->IncreaseNotificationNum();\r
+\r
+       int n_allocated_scalers = rm_resource_list_get_count(scalers);\r
+       RM_TEST_MSG("n_allocated_scalers(%d)", n_allocated_scalers);\r
+       if (n_allocated_scalers == 0)\r
+               return;\r
+\r
+       rm_resource_h scaler = rm_resource_list_get_first(scalers);\r
+       while (scaler) {\r
+               RM_TEST_MSG("scaler(%d:%d)", rm_scaler_get_virtual_id(scaler), rm_scaler_get_source_id(scaler));\r
+               listener->AddScaler(rm_scaler_get_virtual_id(scaler), rm_scaler_get_source_id(scaler));\r
+               scaler = rm_resource_list_get_next(scalers);\r
+       }\r
+}\r
+\r
+TCCallbackListener::TCCallbackListener()\r
+{\r
+       m_n_notification = 0;\r
+}\r
+\r
+TCCallbackListener::~TCCallbackListener()\r
+{\r
+       UnregisterScalerStateChangeCb();\r
+}\r
+\r
+void TCCallbackListener::AddScaler(int vid, int src_id)\r
+{\r
+       m_scalers.insert(std::pair<int, int>(vid, src_id));\r
+}\r
+\r
+bool TCCallbackListener::IsIncluded(int vid, int src_id)\r
+{\r
+       auto it = m_scalers.find(vid);\r
+       if (it == m_scalers.end())\r
+               return false;\r
+\r
+       return (it->second == src_id) ? true:false;\r
+}\r
+\r
+int TCCallbackListener::RegisterScalerStateChangeCb(void)\r
+{\r
+       return rm_subscribe_scaler_state_change(TCCallbackListener::ScalerStateChangeCb, this);\r
+}\r
+\r
+int TCCallbackListener::UnregisterScalerStateChangeCb(void)\r
+{\r
+       return rm_unsubscribe_scaler_state_change(TCCallbackListener::ScalerStateChangeCb);\r
+}\r
diff --git a/ut/testcase/TCCallbackListener.h b/ut/testcase/TCCallbackListener.h
new file mode 100644 (file)
index 0000000..b1c1ce5
--- /dev/null
@@ -0,0 +1,45 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __TC_CALLBACK_LISTENER_H__\r
+#define __TC_CALLBACK_LISTENER_H__\r
+\r
+#include <map>\r
+#include <rm_module_api.h>\r
+\r
+class TCCallbackListener\r
+{\r
+public:\r
+       TCCallbackListener();\r
+       ~TCCallbackListener();\r
+\r
+       static void ScalerStateChangeCb(rm_resource_list_h scalers, void *data);\r
+\r
+       int RegisterScalerStateChangeCb(void);\r
+       int UnregisterScalerStateChangeCb(void);\r
+       void RemoveAllScalers(void) { m_scalers.clear(); }\r
+       void AddScaler(int vid, int src_id);\r
+       bool IsIncluded(int vid, int src_id);\r
+       int GetNotificationNum(void) { return m_n_notification; }\r
+       void ResetNotificationNum(void) { m_n_notification = 0; }\r
+       void IncreaseNotificationNum(void) { m_n_notification++; }\r
+\r
+private:\r
+       std::map<int, int> m_scalers;\r
+       int m_n_notification;\r
+};\r
+\r
+#endif //__TC_CALLBACK_LISTENER_H__
\ No newline at end of file
diff --git a/ut/testcase/TCPlayer.cpp b/ut/testcase/TCPlayer.cpp
new file mode 100644 (file)
index 0000000..8408b30
--- /dev/null
@@ -0,0 +1,316 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <rm_api.h>\r
+#include <rm_module_api.h>\r
+#include <ut_common.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include "TCResource.h"\r
+#include "TCPlayer.h"\r
+\r
+TCPlayer::TCPlayer()\r
+{\r
+       m_handle = 0;\r
+       m_allocated_rsc_index = 0;\r
+       m_rsc_index = 0;\r
+       m_query_index = 0;\r
+       m_n_conflict = 0;\r
+       m_n_conflicted_rsc = 0;\r
+}\r
+\r
+TCPlayer::~TCPlayer()\r
+{\r
+       Unregister();\r
+}\r
+\r
+rm_cb_result TCPlayer::ConflictCb(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       if (!data)\r
+               return RM_CB_RESULT_ERROR;\r
+\r
+       TCPlayer *player = (TCPlayer*) data;\r
+       player->IncreaseConflictNum();\r
+       player->SetConflictedResourcesNum(info->request_num);\r
+\r
+       for (int j = 0; j < info->request_num; j++) {\r
+               player->AddConflictedResource(j+1, info->device_id[j]);\r
+       }\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+int TCPlayer::Register(void)\r
+{\r
+       if (m_handle != 0)\r
+               return RM_ERROR;\r
+\r
+       return rm_register(TCPlayer::ConflictCb, this, &m_handle, NULL);\r
+}\r
+\r
+int TCPlayer::Unregister(void)\r
+{\r
+       int result = RM_ERROR;;\r
+\r
+       RemoveResources();\r
+       RemoveQueries();\r
+       m_allocated_resources.clear();\r
+\r
+       result = rm_unregister(m_handle);\r
+       m_handle = 0;\r
+\r
+       return result;\r
+}\r
+\r
+int TCPlayer::SetPriority(int priority)\r
+{\r
+       return rm_set_priority(m_handle, priority);\r
+}\r
+\r
+int TCPlayer::SetAppId(std::string app_id)\r
+{\r
+       return rm_set_app_id(m_handle, (char*) app_id.c_str());\r
+}\r
+\r
+int TCPlayer::AddResource(int category_id, int state)\r
+{\r
+       TCResource *rsc = new TCResource(category_id, 0, state);\r
+       m_rsc_index++;\r
+       m_requested_resources.insert(std::pair<int, TCResource *>(m_rsc_index, rsc));\r
+       return 0;\r
+}\r
+\r
+int TCPlayer::AddResource(int category_id, int category_option, int state)\r
+{\r
+       TCResource *rsc = new TCResource(category_id, category_option, state);\r
+       m_rsc_index++;\r
+       m_requested_resources.insert(std::pair<int, TCResource *>(m_rsc_index, rsc));\r
+       return 0;\r
+}\r
+\r
+int TCPlayer::AddQuery(int category_id, int category_option, int state)\r
+{\r
+       TCResource *rsc = new TCResource(category_id, category_option, state);\r
+       m_query_index++;\r
+       m_queries.insert(std::pair<int, TCResource *>(m_query_index, rsc));\r
+       return 0;\r
+}\r
+\r
+void TCPlayer::RemoveResources(void)\r
+{\r
+       TCResource *rsc = nullptr;\r
+\r
+       for (auto &it : m_requested_resources) {\r
+               rsc = it.second;\r
+               if (rsc)\r
+                       delete rsc;\r
+       }\r
+       m_requested_resources.clear();\r
+}\r
+\r
+int TCPlayer::GetAudioCategory(std::string codec_name, int mixing_mode)\r
+{\r
+       ri_audio_category_option_request_s audio_option;\r
+       memset(&audio_option, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       audio_option.codec_name = codec_name.c_str();\r
+       audio_option.mixing_mode = (ri_audio_mixing_mode) mixing_mode;\r
+\r
+       return ri_get_capable_audio_category_id(&audio_option);\r
+}\r
+\r
+int TCPlayer::GetCapableVideoCategory(std::string codec_name, int h_size, int v_size, int color_depth, int sampling_format, int framerate)\r
+{\r
+       ri_video_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       opt.codec_name = strndup(codec_name.c_str(), codec_name.length());\r
+       opt.color_depth = color_depth;\r
+       opt.framerate = framerate;\r
+       opt.h_size = h_size;\r
+       opt.v_size = v_size;\r
+       opt.sampling_format = sampling_format;\r
+\r
+       int result = ri_get_capable_video_category_id(&opt);\r
+\r
+       free((void*) opt.codec_name);\r
+       return result;\r
+}\r
+\r
+int TCPlayer::GetCapableImageCategory(std::string codec_name, int w_size, int h_size)\r
+{\r
+       char *codec = strndup(codec_name.c_str(), codec_name.length());\r
+       int result = ri_get_image_category_id(codec, w_size, h_size);\r
+       free(codec);\r
+       return result;\r
+}\r
+\r
+int TCPlayer::GetCapableNDecoderCategory(std::string codec_name, int h_size, int v_size, int color_depth, int sampling_format, int framerate)\r
+{\r
+       ri_video_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       opt.codec_name = strndup(codec_name.c_str(), codec_name.length());\r
+       opt.color_depth = color_depth;\r
+       opt.framerate = framerate;\r
+       opt.h_size = h_size;\r
+       opt.v_size = v_size;\r
+       opt.sampling_format = sampling_format;\r
+\r
+       return ri_get_n_decoder_category_id(&opt);\r
+}\r
+\r
+int TCPlayer::Query(int query_type, int *ans)\r
+{\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       int i = 0;\r
+       int result = RM_ERROR;\r
+       int answer;\r
+\r
+       req.request_num = m_queries.size();\r
+\r
+       for (auto &it : m_queries) {\r
+               TCResource *rsc = it.second;\r
+               req.category_id[i] = (rm_rsc_category_e) rsc->GetCategoryId();\r
+               req.category_option[i] = rsc->GetCategoryOption();\r
+               req.state[i] = (rm_requests_resource_state_e) rsc->GetState();\r
+               i++;\r
+       }\r
+\r
+       result = rm_query(m_handle, (rm_query_type_e) query_type, &req, &answer);\r
+       *ans = answer;\r
+\r
+       return result;\r
+}\r
+\r
+void TCPlayer::RemoveQueries(void)\r
+{\r
+       TCResource *rsc = nullptr;\r
+\r
+       for (auto &it : m_queries) {\r
+               rsc = it.second;\r
+               if (rsc)\r
+                       delete rsc;\r
+       }\r
+       m_queries.clear();\r
+}\r
+\r
+void TCPlayer::AddAllocatedResource(int device_id)\r
+{\r
+       m_allocated_resources.insert(std::pair<int, int>(++m_allocated_rsc_index, device_id));\r
+}\r
+\r
+int TCPlayer::GetAllocatedResourceId(int index)\r
+{\r
+       auto it = m_allocated_resources.find(index);\r
+\r
+       return (it == m_allocated_resources.end()) ? -1 : it->second;\r
+}\r
+\r
+int TCPlayer::AllocateResources(void)\r
+{\r
+       if (m_requested_resources.size() == 0)\r
+               return RM_ERROR;\r
+\r
+       int i = 0;\r
+       int result = RM_ERROR;\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = m_requested_resources.size();\r
+\r
+       for (auto &it : m_requested_resources) {\r
+               TCResource *rsc = it.second;\r
+               req.category_id[i] = (rm_rsc_category_e) rsc->GetCategoryId();\r
+               req.category_option[i] = rsc->GetCategoryOption();\r
+               req.state[i] = (rm_requests_resource_state_e) rsc->GetState();\r
+               i++;\r
+       }\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(allocated));\r
+\r
+       result = rm_allocate_resources(m_handle, &req, &allocated);\r
+\r
+       if (result == RM_OK) {\r
+               for (int j = 0; j < allocated.allocated_num; j++)\r
+                       AddAllocatedResource(allocated.device_id[j]);\r
+       }\r
+\r
+       return result;\r
+}\r
+\r
+int TCPlayer::ReleaseResources(void)\r
+{\r
+       if (m_allocated_resources.size() <= 0)\r
+               return RM_ERROR;\r
+\r
+       int i = 0;\r
+       rm_device_request_s req;\r
+       memset(&req, 0, sizeof(req));\r
+\r
+       req.request_num = m_allocated_resources.size();\r
+\r
+       for (auto &it : m_allocated_resources) {\r
+               req.device_id[i] = it.second;\r
+               i++;\r
+       }\r
+\r
+       m_allocated_resources.clear();\r
+\r
+       return rm_deallocate_resources(m_handle, &req);\r
+}\r
+\r
+int TCPlayer::ReleaseResource(int index)\r
+{\r
+       if (m_allocated_resources.size() <= 0)\r
+               return RM_ERROR;\r
+\r
+       auto it = m_allocated_resources.find(index);\r
+       int device_id = (it == m_allocated_resources.end()) ? -1 : it->second;\r
+\r
+       rm_device_request_s req;\r
+       memset(&req, 0, sizeof(req));\r
+\r
+       req.request_num = 1;\r
+       req.device_id[0] = device_id;\r
+\r
+       m_allocated_resources.erase(index);\r
+\r
+       return rm_deallocate_resources(m_handle, &req);\r
+}\r
+\r
+int TCPlayer::GetActiveAudioOut(void)\r
+{\r
+       return rm_get_active_audio_out(m_handle);\r
+}\r
+\r
+int TCPlayer::GetConflictedResourceId(int index)\r
+{\r
+       auto it = m_conflicted_resources.find(index);\r
+\r
+       return (it == m_conflicted_resources.end()) ? -1 : it->second;\r
+}\r
+\r
+void TCPlayer::AddConflictedResource(int index, int device_id)\r
+{\r
+       m_conflicted_resources.insert(std::pair<int, int>(index, device_id));\r
+}\r
diff --git a/ut/testcase/TCPlayer.h b/ut/testcase/TCPlayer.h
new file mode 100644 (file)
index 0000000..3910ed1
--- /dev/null
@@ -0,0 +1,82 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __TC_PLAYER_H__\r
+#define __TC_PLAYER_H__\r
+\r
+#include <string>\r
+#include <map>\r
+#include <rm_api.h>\r
+\r
+class TCResource;\r
+class TCPlayer\r
+{\r
+public:\r
+       TCPlayer();\r
+       TCPlayer(std::string app_id) { m_app_id = app_id; }\r
+       ~TCPlayer();\r
+\r
+       static rm_cb_result ConflictCb(int handle, rm_callback_type event, rm_device_request_s *info, void *data);\r
+       int Register(void);\r
+       int Unregister(void);\r
+\r
+       int SetPriority(int priority);\r
+       int SetAppId(std::string app_id);\r
+       void SetCustomHandle(int handle) { m_handle = handle;}\r
+\r
+       int AddResource(int category_id, int state);\r
+       int AddResource(int category_id, int category_option, int state);\r
+       void RemoveResources(void);\r
+       int GetAudioCategory(std::string codec_name, int mixing_mode);\r
+       int GetCapableVideoCategory(std::string codec_name, int h_size, int v_size, int color_depth, int sampling_format, int framerate);\r
+       int GetCapableNDecoderCategory(std::string codec_name, int h_size, int v_size, int color_depth, int sampling_format, int framerate);\r
+       int GetCapableImageCategory(std::string codec_name, int h_size, int v_size);\r
+\r
+       int AddQuery(int category_id, int category_option, int state);\r
+       void RemoveQueries(void);\r
+       int Query(int query_type, int *ans);\r
+\r
+       void AddAllocatedResource(int device_id);\r
+       int AllocateResources(void);\r
+       int ReleaseResources(void);\r
+       int ReleaseResource(int index);\r
+       int GetAllocatedResourceId(int index);\r
+       int GetAllocatedResourcesNum(void) { return m_allocated_resources.size(); }\r
+\r
+       void IncreaseConflictNum(void) { m_n_conflict++; }\r
+       int GetConflictNum(void) { return m_n_conflict; }\r
+       void SetConflictedResourcesNum(int n) { m_n_conflicted_rsc = n; }\r
+       int GetConflictedResourcesNum(void) { return m_n_conflicted_rsc; }\r
+       int GetConflictedResourceId(int index);\r
+       void AddConflictedResource(int index, int device_id);\r
+       int GetActiveAudioOut(void);\r
+\r
+private:\r
+       std::map<int, int> m_allocated_resources;\r
+       std::map<int, int> m_conflicted_resources;\r
+       std::map<int, TCResource *> m_requested_resources;\r
+       std::map<int, TCResource *> m_queries;\r
+\r
+       std::string m_app_id;\r
+       int m_handle;\r
+       int m_rsc_index;\r
+       int m_query_index;\r
+       int m_allocated_rsc_index;\r
+       int m_n_conflict;\r
+       int m_n_conflicted_rsc;\r
+};\r
+\r
+#endif //__TC_PLAYER_H__\r
diff --git a/ut/testcase/TCResource.cpp b/ut/testcase/TCResource.cpp
new file mode 100644 (file)
index 0000000..c149966
--- /dev/null
@@ -0,0 +1,28 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "TCResource.h"\r
+\r
+TCResource::TCResource(int category_id, int category_option, int state)\r
+{\r
+       m_category_id = category_id;\r
+       m_category_option = category_option;\r
+       m_state = state;\r
+}\r
+\r
+TCResource::~TCResource()\r
+{\r
+}\r
diff --git a/ut/testcase/TCResource.h b/ut/testcase/TCResource.h
new file mode 100644 (file)
index 0000000..545b5af
--- /dev/null
@@ -0,0 +1,36 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __TC_RESOURCE_H__\r
+#define __TC_RESOURCE_H__\r
+\r
+class TCResource\r
+{\r
+public:\r
+       TCResource(int category_id, int category_option, int state);\r
+       ~TCResource();\r
+\r
+       int GetCategoryId(void) {return m_category_id;}\r
+       int GetCategoryOption(void) {return m_category_option;}\r
+       int GetState(void) {return m_state;}\r
+\r
+private:\r
+       int m_category_id;\r
+       int m_category_option;\r
+       int m_state;\r
+};\r
+\r
+#endif //__TC_RESOURCE_H__
\ No newline at end of file
diff --git a/ut/testcase/common.cpp b/ut/testcase/common.cpp
new file mode 100644 (file)
index 0000000..eaa331b
--- /dev/null
@@ -0,0 +1,294 @@
+/*\r
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved\r
+ * For conditions of distribution and use, see the accompanying LICENSE.Samsung file .\r
+ */\r
+\r
+#include <stdio.h>\r
+#include <unistd.h>\r
+#include <stdlib.h>\r
+#include <sys/stat.h>\r
+#include "gtest/gtest.h"\r
+#include <rm_api.h>\r
+#include <ut_common.h>\r
+\r
+bool read_rm_index(const char *filename, int *data)\r
+{\r
+       FILE *fp = NULL;\r
+       char str[10] = {0,};\r
+       size_t str_size;\r
+\r
+       if (!data) {\r
+               RM_TEST_MSG("invalid input : null data");\r
+               return false;\r
+       }\r
+\r
+       fp = fopen(filename, "rb");\r
+\r
+       if (!fp) {\r
+               RM_TEST_MSG("failed to open (%s) - errno(%d)", filename, errno);\r
+               return false;\r
+       }\r
+\r
+       str_size = fread(str, sizeof(char), sizeof(str)-1, fp);\r
+\r
+       str[str_size] = '\0';\r
+\r
+       if (str_size == 0) {\r
+               fclose(fp);\r
+               return false;\r
+       }\r
+\r
+       *data = atoi(str);\r
+\r
+       fclose(fp);\r
+       fp = NULL;\r
+\r
+       return true;\r
+}\r
+\r
+bool is_8k_model(void)\r
+{\r
+       return false;\r
+}\r
+\r
+static int conflicted;\r
+static int conflicted_cmp;\r
+static int num_of_dealloc_rsc;\r
+\r
+rm_cb_result rm_cb_counting_conflicted(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       ++conflicted;\r
+       num_of_dealloc_rsc = info->request_num;\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+rm_cb_result rm_cb_counting_conflicted_cmp(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       ++conflicted_cmp;\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+rm_cb_result rm_cb_set_conflict_flag(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       conflicted = 1;\r
+       num_of_dealloc_rsc = info->request_num;\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));\r
+\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+rm_cb_result rm_cb_for_conditional_check(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       rm_deallocate_resources(handle, info);\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+int rm_tc_get_conflict_num(void)\r
+{\r
+       return conflicted;\r
+}\r
+\r
+void rm_tc_reset_conflict_num(void)\r
+{\r
+       conflicted = 0;\r
+}\r
+\r
+int rm_tc_get_conflict_num_cmp(void)\r
+{\r
+       return conflicted_cmp;\r
+}\r
+\r
+void rm_tc_reset_conflict_num_cmp(void)\r
+{\r
+       conflicted_cmp = 0;\r
+}\r
+\r
+int rm_tc_get_conflicted_resources_num(void)\r
+{\r
+       return num_of_dealloc_rsc;\r
+}\r
+\r
+void rm_tc_reset_conflicted_resources_num(void)\r
+{\r
+       num_of_dealloc_rsc = 0;\r
+}\r
+\r
+void rm_tc_clear_audio_decoders(void)\r
+{\r
+       RM_TEST_MSG("clear_audio_decoders...");\r
+\r
+       int handle1 = 0;\r
+       if (rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL) != RM_OK) {\r
+               RM_TEST_MSG("failed to register");\r
+               return;\r
+       }\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 2;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request.category_option[0] = 0;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+       request.category_id[1] = RM_CATEGORY_AUDIO_DECODER_SUB;\r
+       request.category_option[1] = 0;\r
+       request.state[1] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       if (rm_allocate_resources(handle1, &request, &allocated) != RM_OK)\r
+               RM_TEST_MSG("failed to clear audio decoders");\r
+\r
+       if (rm_unregister(handle1) != RM_OK)\r
+               RM_TEST_MSG("failed to unregister");\r
+\r
+       RM_TEST_MSG("clear_audio_decoders done...");\r
+}\r
+\r
+void rm_tc_clear_video_decoders(void)\r
+{\r
+       RM_TEST_MSG("clear_video_decoders...");\r
+\r
+       int handle1 = 0;\r
+       if (rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL) != RM_OK) {\r
+               RM_TEST_MSG("failed to register");\r
+               return;\r
+       }\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       if (rm_allocate_resources(handle1, &request, &allocated) != RM_OK)\r
+               RM_TEST_MSG("failed to clear video decoders");\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_H264_UHD_8BIT_60P;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       if (rm_allocate_resources(handle1, &request, &allocated) != RM_OK)\r
+               RM_TEST_MSG("failed to clear video decoders");\r
+\r
+       if (rm_unregister(handle1) != RM_OK)\r
+               RM_TEST_MSG("failed to unregister");\r
+\r
+       RM_TEST_MSG("clear_video_decoders done...");\r
+}\r
+\r
+void rm_tc_template_exceptional_test_case(int vdec1, int vdec2)\r
+{\r
+       //consumer#1\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+\r
+       //alloc\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request->category_option[0] = vdec1 | RM_DEVICE_OPT_MAIN;\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       //consumer#2\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle2, NULL));\r
+\r
+       //alloc\r
+       rm_category_request_s *request2 = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request2, 0, sizeof(rm_category_request_s));\r
+\r
+       request2->request_num = 1;\r
+       request2->category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request2->category_option[0] = vdec2;\r
+       request2->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated2 = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated2, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request2, allocated2));\r
+\r
+       //unregister\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+}\r
+\r
+bool is_support_4k(void)\r
+{\r
+#ifdef RM_TC_SUPPORT_4K\r
+       return true;\r
+#else\r
+       return false;\r
+#endif //RM_TC_SUPPORT_4K\r
+}\r
+\r
+bool is_support_8k(void)\r
+{\r
+#ifdef RM_TC_SUPPORT_8K\r
+       return true;\r
+#else\r
+       return false;\r
+#endif //RM_TC_SUPPORT_8K\r
+}\r
+\r
+bool is_support_av1_120p(void)\r
+{\r
+#ifdef RM_TC_SUPPORT_AV1_120P\r
+       return true;\r
+#else\r
+       return false;\r
+#endif //RM_TC_SUPPORT_AV1_120P\r
+}\r
+\r
+bool use_unified_jpeg_decoder(void)\r
+{\r
+#ifdef RM_TC_USE_UNIFIED_JPEG_DEC\r
+       return true;\r
+#else\r
+       return false;\r
+#endif// RM_TC_USE_UNIFIED_JPEG_DEC\r
+}\r
+\r
+bool is_oscars_unified_jpeg_decoder(void)\r
+{\r
+#ifdef RM_TC_USE_UNIFIED_JPEG_DEC_OSCARS\r
+       return true;\r
+#else\r
+       return false;\r
+#endif\r
+}\r
+\r
+bool is_support_audio_dual_decoding(void)\r
+{\r
+#ifdef RM_TC_SUPPORT_AUDIO_DUAL_DECODING\r
+       return true;\r
+#else\r
+       return false;\r
+#endif //RM_TC_SUPPORT_AUDIO_DUAL_DECODING\r
+}\r
diff --git a/ut/testcase/ut_common.h b/ut/testcase/ut_common.h
new file mode 100644 (file)
index 0000000..d56023c
--- /dev/null
@@ -0,0 +1,66 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#ifndef __UT_COMMON_H__\r
+#define __UT_COMMON_H__\r
+\r
+#include <dlog.h>\r
+#include <glib.h>\r
+#include <rm_api.h>\r
+\r
+#ifdef LOG_TAG\r
+#undef LOG_TAG\r
+#endif//LOG_TAG\r
+\r
+#define LOG_TAG "RSC_MGR_SERVER_TEST"\r
+#define RM_TEST_SLEEP_TIME 1\r
+#define RM_TEST_MSG(fmt, arg...) \\r
+       do { SLOGE(fmt, ##arg); } while (0)\r
+\r
+#define RM_TC_FREE(a) \\r
+               if (a) \\r
+               { \\r
+                       free(a); \\r
+                       a = NULL; \\r
+               }\r
+\r
+bool is_8k_model(void);\r
+bool read_rm_index(const char *filename, int *data);\r
+bool is_support_4k(void);\r
+bool is_support_8k(void);\r
+bool is_support_av1_120p(void);\r
+bool use_unified_jpeg_decoder(void);\r
+bool is_support_audio_dual_decoding(void);\r
+bool is_oscars_unified_jpeg_decoder(void);\r
+\r
+GMainContext *get_callback_thread_context(void);\r
+\r
+rm_cb_result rm_cb_counting_conflicted(int handle, rm_callback_type event, rm_device_request_s *info, void *data);\r
+rm_cb_result rm_cb_counting_conflicted_cmp(int handle, rm_callback_type event, rm_device_request_s *info, void *data);\r
+rm_cb_result rm_cb_set_conflict_flag(int handle, rm_callback_type event, rm_device_request_s *info, void *data);\r
+rm_cb_result rm_cb_for_conditional_check(int handle, rm_callback_type event, rm_device_request_s *info, void *data);\r
+\r
+void rm_tc_template_exceptional_test_case(int vdec1, int vdec2);\r
+\r
+int rm_tc_get_conflict_num(void);\r
+void rm_tc_reset_conflict_num(void);\r
+int rm_tc_get_conflict_num_cmp(void);\r
+void rm_tc_reset_conflict_num_cmp(void);\r
+int rm_tc_get_conflicted_resources_num(void);\r
+void rm_tc_reset_conflicted_resources_num(void);\r
+void rm_tc_clear_audio_decoders(void);\r
+void rm_tc_clear_video_decoders(void);\r
+#endif //__UT_COMMON_H__\r
diff --git a/ut/testcase/ut_main.cpp b/ut/testcase/ut_main.cpp
new file mode 100644 (file)
index 0000000..d8b7ad2
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * 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.
+ */
+
+#include <stdio.h>
+#include <glib.h>
+#include "gtest/gtest.h"
+
+#include <ut_common.h>
+
+static GMainLoop *g_main_loop;
+static gpointer tc_run_loop(gpointer data)
+{
+       RM_TEST_MSG("Run callback thread");
+       GMainLoop *main_loop = (GMainLoop*) data;
+
+       if (main_loop != NULL) {
+               g_main_loop_run(main_loop);
+       }
+
+       RM_TEST_MSG("callback thread terminated");
+       return NULL;
+}
+
+GMainContext *get_callback_thread_context(void)
+{
+       return g_main_loop_get_context(g_main_loop);
+}
+
+GTEST_API_ int main(int argc, char **argv)
+{
+       RM_TEST_MSG("Running main() from ut_main.cpp\n");
+
+       //GMainContext *context = g_main_context_new();
+       g_main_loop = g_main_loop_new(NULL, FALSE);
+       GThread *cb_thread = g_thread_new("rc_cb_thread", tc_run_loop, g_main_loop);
+
+       if (cb_thread == NULL) {
+               g_main_loop_unref(g_main_loop);
+               RM_TEST_MSG("failed to create the callback thread");
+       }
+
+       // Here, your global initialization if necessary
+
+       testing::InitGoogleTest(&argc, argv);
+
+       return RUN_ALL_TESTS();
+}
diff --git a/ut/testcase/ut_tc.cpp b/ut/testcase/ut_tc.cpp
new file mode 100644 (file)
index 0000000..b894c25
--- /dev/null
@@ -0,0 +1,3019 @@
+/*
+ * 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.
+ */
+
+#include "gtest/gtest.h"
+#include <unistd.h>
+
+#include <rm_api.h>
+#include <rm_module_api.h>
+#include <stdlib.h>
+#include <ri-api.h>
+#include <ri-module-api.h>
+#include <rm_debug.h>
+
+#include <sys/stat.h>
+#include <sys/ipc.h>
+#include <sys/msg.h>
+
+#include <ut_common.h>
+#include <TCPlayer.h>
+
+static int conflicted = 0;
+static int conflicted4 = 0;
+
+static int num_of_dealloc_rsc = 0;
+int category_call_num[50];
+int category_opt_call_num[5000];
+
+//define for MSGQ TC
+typedef struct {
+       int category_id;
+       int device_id;
+} rms_conflicted_resource_info_s;
+
+typedef struct {
+       long    data_type;
+       int     type;
+       int     result;
+       int     resource_num;
+       int     resource[10];
+       int resource_state[10];
+       int     is_available;
+       int     handle;
+       int error_type;
+} rms_msg_response;
+
+rm_cb_result conflict_cb(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       conflicted = 1;
+
+       RM_TEST_MSG("conflict_cb called");
+       RM_TEST_MSG("conflicted resources...");
+
+       for (int i = 0; i < info->request_num; i++) {
+               RM_TEST_MSG("[%d] device id : %d", i+1, info->device_id[i]);
+       }
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+rm_cb_result conflict_cb2(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       conflicted = 1;
+       num_of_dealloc_rsc = info->request_num;
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+
+       return RM_CB_RESULT_OK;
+}
+
+static rm_cb_result conflict_cb3(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       ++conflicted;
+       num_of_dealloc_rsc = info->request_num;
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+rm_cb_result conflict_cb4(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       conflicted4 = 1;
+
+       RM_TEST_MSG("conflict_cb4 called");
+       RM_TEST_MSG("conflicted resources...");
+
+       for (int i = 0; i < info->request_num; i++) {
+               RM_TEST_MSG("[%d] device id : %d", i+1, info->device_id[i]);
+       }
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+int flag1=0;
+int flag2=0;
+int endflag=0;
+pthread_t t1,t2,t3;
+rm_cb_result cb1(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       flag2=1;
+       usleep(1000*2000);
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+rm_cb_result cb2(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+void *thread_main1(void*)
+{
+       int handle=0;
+       EXPECT_EQ(RM_OK,rm_register(cb1, NULL, &handle, NULL));
+
+       //alloc
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 1;
+       request->category_id[0] = RM_CATEGORY_EXT_VIDEO_SRC;
+       request->category_option[0] = 0;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK,rm_allocate_resources(handle, request, allocated));
+       flag1=1;
+       while (true) {
+               if (endflag) {
+                       EXPECT_EQ(RM_OK, rm_unregister(handle));
+                       pthread_exit(0);
+               }
+               usleep(1000);
+       }
+}
+void *thread_main2(void*)
+{
+       int handle=0;
+       while (true) {
+               if (flag1) {
+                       EXPECT_EQ(RM_OK,rm_register(cb2, NULL, &handle, NULL));
+                       //alloc
+                       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+                       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+                       request->request_num = 1;
+                       request->category_id[0] = RM_CATEGORY_EXT_VIDEO_SRC;
+                       request->category_option[0] = 0;
+                       request->state[0] = RM_STATE_EXCLUSIVE;
+
+                       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+                       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+                       EXPECT_EQ(RM_OK,rm_allocate_resources(handle, request, allocated));
+                       flag1=0;
+
+               }
+               if (endflag) {
+                       EXPECT_EQ(RM_OK, rm_unregister(handle));
+                       pthread_exit(0);
+               }
+               usleep(1000*1000);
+       }
+}
+
+void *thread_main3(void*)
+{
+       int handle=0;
+       while (true) {
+               if (flag2) {
+                       EXPECT_EQ(RM_OK,rm_register(cb2, NULL, &handle, NULL));
+
+                       //alloc
+                       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+                       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+                       request->request_num = 1;
+                       request->category_id[0] = RM_CATEGORY_EXT_VIDEO_SRC;
+                       request->category_option[0] = 0;
+                       request->state[0] = RM_STATE_EXCLUSIVE;
+
+                       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+                       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+                       EXPECT_EQ(RM_OK,rm_allocate_resources(handle, request, allocated));
+                       EXPECT_EQ(RM_OK, rm_unregister(handle));
+                       endflag=1;
+                       pthread_exit(0);
+               }
+               usleep(1000*1000);
+       }
+}
+
+/* default scenario
+ * 1. register and get a handle
+ * 2. query
+ * 3. request to alloc
+ * 4. request to dealloc
+ * 5. unregister
+ */
+
+TEST(ut_rm_api, rm_default)
+{
+       int handle = 0;
+
+       //register
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       //query
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 1;
+       request->category_id[0] = RM_CATEGORY_EXT_VIDEO_SRC;
+       request->category_option[0] = 0;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       int result = 0;
+
+       EXPECT_EQ(RM_OK, rm_query(handle, RM_QUERY_ALLOCATION, request, &result));
+       EXPECT_EQ(1, result);
+
+       //alloc
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, request, allocated));
+
+       EXPECT_EQ(RM_OK, rm_query(handle, RM_QUERY_ALLOCATION, request, &result));
+       EXPECT_EQ(0, result);
+
+       //dealloc
+       rm_device_request_s *dealloc_request = (rm_device_request_s*) malloc (sizeof(rm_device_request_s));
+       memset((void*) dealloc_request, 0, sizeof(rm_device_request_s));
+
+       dealloc_request->request_num = 1;
+       dealloc_request->device_id[0] = (int)RM_DEVICE_EXT_VIDEO_SRC;
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, dealloc_request));
+
+       EXPECT_EQ(RM_OK, rm_query(handle, RM_QUERY_ALLOCATION, request, &result));
+       EXPECT_EQ(1, result);
+
+       //unregister
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+/* default scenario
+ * 1. register and get a handle
+ * 2. query
+ * 3. unregister
+ */
+
+TEST(ut_rm_api, rm_query_terminate)
+{
+       int handle = 0;
+
+       //register
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       //query
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 0;
+       request->category_id[0] = RM_CATEGORY_NONE;
+       request->category_option[0] = 0;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       int result = 0;
+
+       EXPECT_EQ(RM_OK, rm_query(handle, RM_QUERY_TERMINATE, request, &result));
+
+       // this process has not been killed by resource manager. so result should be 0.
+       EXPECT_EQ(0, result);
+
+       //unregister
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+/* conflict scenario
+ * 1. [consumer#1] register and get a handle
+ * 2. [consumer#1] request to alloc
+ * 3. [consumer#2] register and get a handle
+ * 4. [consumer#2] request to alloc
+ * ----- resource conflict is occured!! -----
+ * 5. [consumer#1] get cb message and dealloc
+ * 6. [consumer#2] alloc success
+ * 7. [consumer#2] dealoc
+ * 8. [consumer#1] unregister
+ * 9. [consumer#2] unregister
+ */
+TEST(ut_rm_api, rm_conflict)
+{
+       RM_TEST_MSG("rm_conflict start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_EXT_VIDEO_SRC, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_EXT_VIDEO_SRC, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+       EXPECT_EQ(RM_OK, player2->ReleaseResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       RM_TEST_MSG("rm_conflict end...");
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+
+/* set priority scenario
+ * 1. register and get a handle
+ * 2. set priority
+ * 3. unregister
+ */
+TEST(ut_rm_api, rm_priority)
+{
+       int priority = 50;
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->SetPriority(priority));
+       EXPECT_EQ(RM_OK, player->Unregister());
+
+       delete player;
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_unregister_invalid_handle01)
+{
+       //insert invalid rm handle
+       EXPECT_EQ(RM_ERROR, rm_unregister(99));
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+TEST(ut_rm_api, rm_set_app_id)
+{
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->SetAppId("org.tizen.rm.test"));
+       EXPECT_EQ(RM_OK, player->Unregister());
+
+       delete player;
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_set_app_id_max)
+{
+       const char *app_id = "org.tizen.test1test2test3test4test5test6test7test8test9test10test11test12test13test14test15test16test17test18test19test20test21test22test23test24test25test26test27test28test29test30test31test32test33test34test35test1test2test3test4test5test6test7test8test9test10test11test12test13test14test15test16test17test18test19test20test21test22test23test24test25test26test27test28test29test30test31test32test33test34test35test1test2test3test4test5test6test7test8test9test10test11test12test13test14test15test16test17test18test19test20test21test22test23test24test25test26test27test28test29test30test31test32test33test34test35test1test2test3test4test5test6test7test8test9test10test11test12test13test14test15test16test17test18test19test20test21test22test23test24test25test26test27test28test29test30test31test32test33test34test35test1test2test3test4test5test6test7test8test9test10test11test12test13test14test15test16test17test18test19test20test21test22test23test24test25test26test27test28test29test30test31test32test33test34test35test1test2test3test4test5test6test7test8test9test10test11test12test13test14test15test16test17test18test19test20test21test22test23test24test25test26test27test28test29test30test31test32test33test34test35";
+
+       RM_TEST_MSG("rm_set_app_id_max start");
+       RM_TEST_MSG("app id len (%d)", strlen(app_id));
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_NE(RM_OK, player->SetAppId(app_id));
+       EXPECT_EQ(RM_OK, player->Unregister());
+
+       delete player;
+
+       RM_TEST_MSG("rm_set_app_id_max end");
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_set_app_id_with_invalid_handle)
+{
+       TCPlayer *player = new TCPlayer();
+
+       player->SetCustomHandle(1);
+       EXPECT_EQ(RM_ERROR, player->SetAppId("org.tizen.rm.test"));
+
+       delete player;
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_set_app_id_with_invalid_id_null)
+{
+       int handle = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       EXPECT_EQ(RM_ERROR, rm_set_app_id(handle, NULL));
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+TEST(ut_rm_api, rm_set_app_id_with_invalid_id_long)
+{
+       int handle = 0;
+       char app_id[2048] = {0,};
+       snprintf(app_id, 2048, "%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s", "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
+       "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa");
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       EXPECT_EQ(RM_ERROR, rm_set_app_id(handle, app_id));
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+TEST(ut_rm_api, ri_get_video_category_id_fhd)
+{
+       //MPEG1
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P, ri_get_video_category_id("MPEG1", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_60P, ri_get_video_category_id("MPEG1", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("MPEG1", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //MPEG2
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P, ri_get_video_category_id("MPEG2", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_60P, ri_get_video_category_id("MPEG2", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("MPEG2", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //MPEG4
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, ri_get_video_category_id("MPEG4", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P, ri_get_video_category_id("MPEG4", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("MPEG4", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //H263
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_30P, ri_get_video_category_id("H263", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_60P, ri_get_video_category_id("H263", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("H263", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //H264
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P, ri_get_video_category_id("H264", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P, ri_get_video_category_id("H264", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("H264", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //HEVC
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P, ri_get_video_category_id("HEVC", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_60P, ri_get_video_category_id("HEVC", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_10BIT_420_60P, ri_get_video_category_id("HEVC", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //VP8
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_30P, ri_get_video_category_id("VP8", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_60P, ri_get_video_category_id("VP8", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("VP8", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //VP9
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_30P, ri_get_video_category_id("VP9", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_60P, ri_get_video_category_id("VP9", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_60P, ri_get_video_category_id("VP9", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //RV
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_30P, ri_get_video_category_id("RV", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_60P, ri_get_video_category_id("RV", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("RV", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //WMV9
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_30P, ri_get_video_category_id("WMV", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_60P, ri_get_video_category_id("WMV", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("WMV", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //AVS
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_30P, ri_get_video_category_id("AVS", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_60P, ri_get_video_category_id("AVS", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("AVS", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //AVS+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_30P, ri_get_video_category_id("AVS+", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_60P, ri_get_video_category_id("AVS+", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("AVS+", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+
+       //H264_MVC
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_30P, ri_get_video_category_id("H264_MVC", 8, 1920, 30, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H264_FHD_8BIT_60P, ri_get_video_category_id("H264_MVC", 8, 1920, 60, RI_SAMPLING_FORMAT_420));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, ri_get_video_category_id("H264_MVC", 10, 1920, 60, RI_SAMPLING_FORMAT_420));
+}
+
+TEST(ut_rm_api, ri_get_jpeg_category_id)
+{
+       EXPECT_EQ(RI_CATEGORY_MJPEG_DECODER_FHD, ri_get_jpeg_category_id("MJPEG", 1920));
+       EXPECT_EQ(RI_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED, ri_get_jpeg_category_id("JPEG", 1920));
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+
+TEST(ut_rm_api, ri_get_sub_jpeg_category_id)
+{
+       EXPECT_EQ(RI_CATEGORY_JPEG_DECODER_FHD, ri_get_sub_jpeg_category_id("JPEG", 1920, 1080));
+
+       int expected_result = RI_CATEGORY_JPEG_DECODER_UHD;
+       EXPECT_EQ(expected_result, ri_get_sub_jpeg_category_id("JPEG", 3840, 1920));
+}
+
+//assign available video decoder
+TEST(ut_rm_api, rm_allocate_available_vdec)
+{
+
+       RM_TEST_MSG("rm_allocate_available_vdec start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+       EXPECT_EQ((int) RI_DEVICE_VIDEO_DECODER_MAIN, player->GetAllocatedResourceId(1));
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, 0, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+       EXPECT_EQ((int) RI_DEVICE_VIDEO_DECODER_SUB, player2->GetAllocatedResourceId(1));
+
+       EXPECT_EQ(RM_OK, player->ReleaseResources());
+       EXPECT_EQ(RM_OK, player2->ReleaseResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+       RM_TEST_MSG("rm_allocate_available_vdec end...");
+}
+
+//assign main video decoder
+TEST(ut_rm_api, rm_allocate_main_vdec)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+       EXPECT_EQ((int) RI_DEVICE_VIDEO_DECODER_MAIN, player->GetAllocatedResourceId(1));
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+       EXPECT_EQ((int) RI_DEVICE_VIDEO_DECODER_MAIN, player2->GetAllocatedResourceId(1));
+
+       EXPECT_EQ(RM_OK, player2->ReleaseResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+#define RMS_HANDLE_MIN 101
+#define RMS_HANDLE_NUM_MAX 100
+
+TEST(ut_rm_api, rm_handle_assignment)
+{
+       const int rms_handle_max_num = 100;
+       int handle[rms_handle_max_num];
+
+       for (int i = 0; i < rms_handle_max_num; i++)
+               handle[i] = -1;
+
+       // STEP#1 allocate 50 handles
+       for (int i = 0; i < 50; i++) {
+               EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle[i], NULL));
+               EXPECT_LE(RMS_HANDLE_MIN, handle[i]);
+               EXPECT_GE(RMS_HANDLE_MIN+RMS_HANDLE_NUM_MAX, handle[i]);
+       }
+
+       // STEP#2 release 5 handles
+       for (int i = 0; i < 5; i++) {
+               EXPECT_EQ(RM_OK, rm_unregister(handle[i]));
+               handle[i] = -1;
+       }
+
+       // STEP#3 allocate 50 handles
+       for (int i = 50; i < 100; i++) {
+               EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle[i], NULL));
+               EXPECT_LE(RMS_HANDLE_MIN, handle[i]);
+               EXPECT_GE(RMS_HANDLE_MIN+RMS_HANDLE_NUM_MAX, handle[i]);
+       }
+
+       // STEP#4 release 95 handles
+       for (int i = 5; i < 100; i++) {
+               EXPECT_EQ(RM_OK, rm_unregister(handle[i]));
+               handle[i] = -1;
+       }
+
+       // STEP#5 allocate 50 handles
+       for (int i = 0; i < 50; i++) {
+               EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle[i], NULL));
+               EXPECT_LE(RMS_HANDLE_MIN, handle[i]);
+               EXPECT_GE(RMS_HANDLE_MIN+RMS_HANDLE_NUM_MAX, handle[i]);
+       }
+
+       // STEP#6 release 15 handles
+       for (int i = 0; i < 15; i++) {
+               EXPECT_EQ(RM_OK, rm_unregister(handle[i]));
+               handle[i] = -1;
+       }
+
+       // STEP#7 allocate 50 handles
+       for (int i = 50; i < 100; i++) {
+               EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle[i], NULL));
+               EXPECT_LE(RMS_HANDLE_MIN, handle[i]);
+               EXPECT_GE(RMS_HANDLE_MIN+RMS_HANDLE_NUM_MAX, handle[i]);
+       }
+
+       // STEP#8 free all allocated handles
+       for (int i = 0; i < 100; i++) {
+               if (handle[i] != -1) {
+                       EXPECT_EQ(RM_OK, rm_unregister(handle[i]));
+                       handle[i] = -1;
+               }
+       }
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+/* scenario
+ * 1. allocate mfd0
+ * 2. allocate mfd1
+ * 3. request allocate dvde0 (vp9 uhd 60p)
+ * 4. mfd0 is deallocated
+ * 5. allocated dvde0
+ */
+TEST(ut_rm_api, rm_conflict02)
+{
+       RM_TEST_MSG("rm_conflict02 start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       TCPlayer *player3 = new TCPlayer();
+       player3->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_60P, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player3->Register());
+       if (is_support_4k()) {
+               EXPECT_EQ(RM_OK, player3->AllocateResources());
+       } else {
+               EXPECT_NE(RM_OK, player3->AllocateResources());
+       }
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+       EXPECT_EQ(RM_OK, player3->Unregister());
+
+       delete player;
+       delete player2;
+       delete player3;
+
+       sleep(RM_TEST_SLEEP_TIME);
+       RM_TEST_MSG("rm_conflict02 end...");
+}
+
+/* issue : category does not return retirable consumer if free state resource exists
+ *** scenario
+ * 1. allocate demux & scaler : by tv main stream(handle1)
+ * 2. allocate sub scaler : by other app(handle2)
+ * 3. request allocate demux & sub scaler : by tv pip stream(handle3)
+ * 4. only sub scaler is deallocated
+ * 5. successfully allcated demux & sub scaler without demux conflict
+ */
+TEST(ut_rm_api, rm_conflict03)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_SCALER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       TCPlayer *player3 = new TCPlayer();
+       player3->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+       player3->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player3->Register());
+       EXPECT_EQ(RM_OK, player3->AllocateResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+       EXPECT_EQ(RM_OK, player3->Unregister());
+
+       delete player;
+       delete player2;
+       delete player3;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+/* issue : same consumer allocates same resources including video decoder(main only opt)
+ *** scenario
+ * 1. allocate mainout and a.dec
+ * 2. allocate v.dec(main only) and scaler
+ * 3. allocate mainout and a.dec again => expected result : alloc failure
+ * 4. allocate v.dec(main only) and scaler again => expected result : alloc failure
+ */
+TEST(ut_rm_api, rm_conflict04)
+{
+       RM_TEST_MSG("rm_conflict04 start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_AUDIO_MAIN_OUT, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_AUDIO_DECODER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+       player2->AddResource(RM_CATEGORY_SCALER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(RM_ERROR, player->AllocateResources());
+       EXPECT_EQ(RM_ERROR, player2->AllocateResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+       RM_TEST_MSG("rm_conflict04 end...");
+
+}
+
+TEST(ut_rm_api, rm_conflict05)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+
+       if (is_support_4k())
+               EXPECT_EQ(RM_OK, player->AllocateResources());
+       else
+               EXPECT_NE(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+/* issue : video decoder(mem cluster) conflict
+ */
+TEST(ut_rm_api, rm_conflict09)
+{
+       RM_TEST_MSG("rm_conflict09 start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(1, player->GetConflictNum());
+       EXPECT_EQ(1, player->GetConflictedResourcesNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("rm_conflict09 end...");
+}
+
+/* issue : video decoder(mem cluster) conflict
+ */
+TEST(ut_rm_api, rm_conflict10)
+{
+       RM_TEST_MSG("rm_conflict10 start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+       player2->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(1, player->GetConflictNum());
+       EXPECT_EQ(1, player->GetConflictedResourcesNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+       RM_TEST_MSG("rm_conflict10 end...");
+}
+
+
+
+/* issue : no conflict
+ */
+TEST(ut_rm_api, rm_conflict12)
+{
+       RM_TEST_MSG("rm_conflict12 start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(0, player->GetConflictNum());
+       EXPECT_EQ(0, player->GetConflictedResourcesNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("rm_conflict12 end...");
+}
+
+/* issue : no conflict
+ */
+TEST(ut_rm_api, rm_conflict13)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+       player2->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(0, player->GetConflictNum());
+       EXPECT_EQ(0, player->GetConflictedResourcesNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+/* issue : no conflict
+ */
+TEST(ut_rm_api, rm_conflict15)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_DEMUX, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(0, player->GetConflictNum());
+       EXPECT_EQ(0, player->GetConflictedResourcesNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+/* issue : 2 video decoders are allocated
+ */
+TEST(ut_rm_api, rm_alloc_2_vdecs1)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+       EXPECT_EQ(RM_OK, player->Unregister());
+
+       delete player;
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+/* issue : 2 video decoders are allocated
+ */
+TEST(ut_rm_api, rm_alloc_2_vdecs2)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       player->RemoveResources();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_STATE_EXCLUSIVE);
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+
+       delete player;
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+//t1 and t2 cause resource conflict and t3 request while force allocation(send internal msgq)
+TEST(ut_rm_api, rm_conflict_internal_msg_q)
+{
+       pthread_create(&t1,NULL,&thread_main1,(void*)1);
+       pthread_create(&t2,NULL,&thread_main2,(void*)2);
+       pthread_create(&t3,NULL,&thread_main3,(void*)3);
+       int status=0;
+       pthread_join(t1,(void**)&status);
+       pthread_join(t2,(void**)&status);
+       pthread_join(t3,(void**)&status);
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_test_request_of_invisible_app)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_EXT_VIDEO_SRC, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_EXT_VIDEO_SRC, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->SetAppId("Invalid_AppID"));
+       EXPECT_NE(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(0, player->GetConflictNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+
+TEST(ut_rm_api, rm_test_alloc_sub_vdec)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER_SUB, (RM_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P | RM_DEVICE_OPT_SUB), RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+       EXPECT_EQ(1, player->GetAllocatedResourcesNum());
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_SUB, player->GetAllocatedResourceId(1));
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER_SUB, (RM_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P | RM_DEVICE_OPT_SUB), RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+       EXPECT_EQ(1, player2->GetAllocatedResourcesNum());
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_SUB, player2->GetAllocatedResourceId(1));
+
+       EXPECT_EQ(1, player->GetConflictNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+}
+
+void template_exceptional_test_case(int vdec1, int vdec2)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, (vdec1 | RM_DEVICE_OPT_MAIN), RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, vdec2, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+static int local_handle = 0;
+
+rm_cb_result conflict_cb_test_async_unregister(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       EXPECT_EQ(RM_OK, rm_unregister(local_handle));
+       usleep(2000*1000);
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+TEST(ut_rm_api, rm_async_unregister)
+{
+       //consumer#local
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &local_handle, NULL));
+
+       //alloc
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 1;
+       request->category_id[0] = RM_CATEGORY_SCALER_SUB;
+       request->category_option[0] = 0;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(local_handle, request, allocated));
+
+       //consumer#1
+       int handle1 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_test_async_unregister, NULL, &handle1, NULL));
+
+       //alloc
+       rm_category_request_s *request1 = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request1, 0, sizeof(rm_category_request_s));
+
+       request1->request_num = 1;
+       request1->category_id[0] = RM_CATEGORY_CAMERA;
+       request1->category_option[0] = 0;
+       request1->state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s *allocated1 = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated1, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request1, allocated1));
+
+       //consumer#2
+       int handle2 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle2, NULL));
+
+       rm_device_return_s *allocated2 = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated2, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request1, allocated2));
+       rm_unregister(handle1);
+       rm_unregister(handle2);
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+
+
+TEST(ut_rm_api, vdapi_rm_allocate_invalid_resource_n)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_AUDIO_SPDIF_ES_OUTPUT, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_NE(RM_OK, player->AllocateResources());
+       EXPECT_EQ(RM_OK, player->Unregister());
+
+       delete player;
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_allocate_with_low_priority)
+{
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_EXT_VIDEO_SRC, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->SetPriority(10000));
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_EXT_VIDEO_SRC, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->SetPriority(10));
+       EXPECT_NE(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_alloc_uhd_jpeg_conflict)
+{
+       if (ri_get_max_video_decoder_num() >=4 )
+               return;
+
+       if (is_oscars_unified_jpeg_decoder())
+               return;
+
+       if (!is_support_4k())
+               return;
+
+       RM_TEST_MSG("rm_alloc_uhd_jpeg_conflict start");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, (RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_10BIT_420_30P | RM_DEVICE_OPT_MAIN), RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_JPEG_DECODER, RM_CATEGORY_JPEG_DECODER_UHD, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(1, player->GetConflictNum());
+       EXPECT_EQ(1, player->GetConflictedResourcesNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       RM_TEST_MSG("rm_alloc_uhd_jpeg_conflict end");
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, rm_test_mem_cluster_conflict_by_invisible_app_request)
+{
+       RM_TEST_MSG("rm_test_mem_cluster_conflict_by_invisible_app_request start...");
+
+       TCPlayer *player = new TCPlayer();
+       player->AddResource(RM_CATEGORY_AUDIO_DECODER, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player->Register());
+       EXPECT_EQ(RM_OK, player->AllocateResources());
+
+       TCPlayer *player2 = new TCPlayer();
+       player2->AddResource(RM_CATEGORY_AUDIO_DECODER_PRIMARY, RM_STATE_EXCLUSIVE);
+
+       EXPECT_EQ(RM_OK, player2->Register());
+       EXPECT_EQ(RM_OK, player2->SetAppId("Invalid_AppID"));
+       EXPECT_NE(RM_OK, player2->AllocateResources());
+
+       EXPECT_EQ(0, player->GetConflictNum());
+
+       EXPECT_EQ(RM_OK, player->Unregister());
+       EXPECT_EQ(RM_OK, player2->Unregister());
+
+       delete player;
+       delete player2;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("rm_test_mem_cluster_conflict_by_invisible_app_request end...");
+}
+
+TEST(ut_rm_api, rm_exlusive_conditional_2)
+{
+       int handle;
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_for_conditional_check, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       rm_device_return_s allocated;
+
+       memset((void*)&allocated, 0, sizeof(rm_device_return_s));
+       memset((void*)&request, 0, sizeof(rm_category_request_s));
+
+       // Get 60p decoder to make other consumer release resources
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_video_category_id("MPEG2", 8, 1920, 60, 0);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+
+       rm_device_request_s release_request;
+
+       memset((void*)&release_request, 0, sizeof(rm_device_request_s));
+
+       release_request.request_num = 1;
+       release_request.device_id[0] = allocated.device_id[0];
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, &release_request));
+
+       memset((void*)&allocated, 0, sizeof(rm_device_return_s));
+       memset((void*)&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_video_category_id("MPEG2", 8, 1920, 30, 0);
+       request.state[0] = RM_STATE_EXCLUSIVE_CONDITIONAL;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+TEST(ut_rm_api, rm_clear_msgq_on_allocate)
+{
+       int handle;
+       rm_register(conflict_cb, NULL, &handle, NULL);
+       int temphandle = handle;
+       rm_unregister(handle);
+       int message_queue_tx = msgget((key_t)8212, 0666| IPC_CREAT);
+       rms_msg_response response;
+       memset(&response, 0, sizeof(rms_msg_response));
+       response.handle = temphandle;
+       response.data_type = temphandle;
+       response.type = 3;
+       response.result = 1;
+
+       for (int i = 0; i < 13; i++) {
+               msgsnd(message_queue_tx, (void*) (&response), sizeof(rms_msg_response) - sizeof(long), 0) ;
+               usleep(10000);
+       }
+
+       int prev_handle = -1;
+
+       while (1) {
+               if (rm_register(conflict_cb, NULL, &handle, NULL) != RM_OK) {
+                       RM_TEST_MSG("failed to get a new handle");
+                       break;
+               }
+
+               if (prev_handle != -1)
+                       rm_unregister(prev_handle);
+
+               if (handle == temphandle)
+                       break;
+
+               prev_handle = handle;
+       }
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_CAMERA;
+       request.category_option[0] = 0;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle,&request,&allocated));
+
+       rm_unregister(temphandle);
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+}
+
+
+TEST(ut_rm_api, conflict_cb_should_not_be_called_on_same_consumer)
+{
+       int handle;
+       rm_device_return_s allocated;
+       rm_category_request_s request;
+
+       conflicted = 0;
+
+       RM_TEST_MSG("conflict_cb_should_not_be_called_on_same_consumer start");
+
+       memset((void*)&allocated, 0, sizeof(rm_device_return_s));
+       memset((void*)&request, 0, sizeof(rm_category_request_s));
+
+       rm_register(conflict_cb, NULL, &handle, NULL);
+
+       ri_video_category_option_request_s *opt = (ri_video_category_option_request_s*) malloc(sizeof(ri_video_category_option_request_s));
+       opt->codec_name = "MPEG2";
+       opt->color_depth = 8;
+       opt->framerate = 30;
+       opt->h_size = 1920;
+       opt->v_size = 1080;
+       opt->sampling_format = RI_SAMPLING_FORMAT_420;
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(opt);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+       EXPECT_EQ(0, conflicted);
+
+       free(opt);
+
+       rm_unregister(handle);
+
+       RM_TEST_MSG("conflict_cb_should_not_be_called_on_same_consumer done");
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, should_be_able_to_take_mem_conflicted_resource_and_conflict_cb_should_not_be_called_on_same_consumer)
+{
+       int handle;
+       int handle2;
+       rm_device_return_s allocated;
+       rm_category_request_s request;
+
+       conflicted = 0;
+       conflicted4 = 0;
+
+       RM_TEST_MSG("should_be_able_to_take_mem_conflicted_resource_and_conflict_cb_should_not_be_called_on_same_consumer start");
+
+       memset((void*)&allocated, 0, sizeof(rm_device_return_s));
+       memset((void*)&request, 0, sizeof(rm_category_request_s));
+
+       rm_register(conflict_cb4, NULL, &handle, NULL);
+
+       RM_TEST_MSG("assigned handle : %d", handle);
+
+       ri_video_category_option_request_s *opt = (ri_video_category_option_request_s*) malloc(sizeof(ri_video_category_option_request_s));
+       opt->codec_name = "MPEG2";
+       opt->color_depth = 8;
+       opt->framerate = 30;
+       opt->h_size = 1920;
+       opt->v_size = 1080;
+       opt->sampling_format = RI_SAMPLING_FORMAT_420;
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(opt);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+
+       rm_register(conflict_cb, NULL, &handle2, NULL);
+
+       RM_TEST_MSG("assigned handle2 : %d", handle2);
+
+       opt->codec_name = "H264";
+       opt->color_depth = 8;
+       opt->framerate = 30;
+       opt->h_size = 1920;
+       opt->v_size = 1080;
+       opt->sampling_format = RI_SAMPLING_FORMAT_420;
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(opt);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(0, conflicted);
+       EXPECT_EQ(1, conflicted4);
+
+       free(opt);
+
+       rm_unregister(handle);
+       rm_unregister(handle2);
+
+       RM_TEST_MSG("should_be_able_to_take_mem_conflicted_resource_and_conflict_cb_should_not_be_called_on_same_consumer done");
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+
+}
+
+TEST(ut_rm_api, ri_get_jpeg_category_id_p)
+{
+       EXPECT_EQ(RI_CATEGORY_MJPEG_DECODER_FHD, ri_get_jpeg_category_id("MJPEG", 1920));
+       EXPECT_EQ(RI_CATEGORY_MJPEG_DECODER_NOT_SUPPORTED, ri_get_jpeg_category_id("JPEG", 1920));
+}
+
+
+TEST(ut_rm_api, ri_get_sub_jpeg_category_id_p)
+{
+       EXPECT_EQ(RI_CATEGORY_JPEG_DECODER_FHD, ri_get_sub_jpeg_category_id("JPEG", 1920, 1080));
+
+       int expected_result = RI_CATEGORY_JPEG_DECODER_UHD;
+       EXPECT_EQ(expected_result, ri_get_sub_jpeg_category_id("JPEG", 3840, 1920));
+}
+
+TEST(ut_rm_api, ri_get_device_path_by_device_id_p)
+{
+       char *path = NULL;
+       EXPECT_EQ(RI_OK, ri_get_device_path_by_device_id(RI_DEVICE_AUDIO_MAIN_OUT,&path));
+       EXPECT_STREQ("alsa_control_main_out",path);
+}
+
+TEST(ut_rm_api, ri_get_omx_comp_name_by_device_id_p)
+{
+       char *name = NULL;
+       EXPECT_EQ(RI_OK, ri_get_omx_comp_name_by_device_id(RI_DEVICE_AUDIO_DECODER,&name));
+       EXPECT_STREQ("OMX.SDP.AUDIO.DECODER.INST0",name);
+}
+
+TEST(ut_rm_api, ri_get_category_type_by_device_id_p)
+{
+       int category_id = 0;
+       EXPECT_EQ(RI_OK, ri_get_category_type_by_device_id(RI_DEVICE_AUDIO_MAIN_OUT, &category_id));
+       EXPECT_EQ(RI_CATEGORY_AUDIO_MAIN_OUT,category_id);
+}
+
+TEST(ut_rm_api, ri_get_device_list_p)
+{
+       int num_of_device = 0;
+       ri_device_common_attr_s *device_list = NULL;
+       EXPECT_EQ(RI_OK, ri_get_device_list(&num_of_device, &device_list));
+}
+
+TEST(ut_rm_api, ri_get_device_id_p)
+{
+       char path[22] = "alsa_control_main_out";
+       EXPECT_EQ(RI_DEVICE_AUDIO_MAIN_OUT, ri_get_device_id(path));
+}
+
+TEST(ut_rm_api, ri_get_device_info_for_fastboot_p)
+{
+       char *node = NULL;
+       ri_rsc_category_e cat = RI_CATEGORY_DEMUX;
+       EXPECT_EQ(RI_OK, ri_get_device_info_for_fastboot(cat, &node));
+}
+
+TEST(ut_rm_api, ri_get_video_category_id_by_codec_p)
+{
+       ri_category_option_request_s request_opt;
+       ri_category_option_return_s return_opt;
+       memset(&request_opt,0,sizeof(ri_category_option_request_s));
+       request_opt.codec_name = "HEVC";
+       request_opt.preferred_mode = RI_VDEC_MODE_SPECIFIC;
+       EXPECT_EQ(RI_OK,ri_get_video_category_id_by_codec(&request_opt, &return_opt));
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_p)
+{
+       ri_video_category_option_request_s *opt = (ri_video_category_option_request_s*) malloc(sizeof(ri_video_category_option_request_s));
+       opt->codec_name = "HEVC";
+       opt->color_depth = 8;
+       opt->framerate = 30;
+       opt->h_size = 1920;
+       opt->v_size = 1080;
+       opt->sampling_format = RI_SAMPLING_FORMAT_420;
+
+       int id = ri_get_capable_video_category_id(opt);
+       EXPECT_EQ(id, RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P);
+
+       opt->h_size = 1920;
+       opt->v_size = 1090;
+       id = ri_get_capable_video_category_id(opt);
+
+       int expected_result = (is_support_4k()) ? RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P:RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED;
+       EXPECT_EQ(id, expected_result);
+
+       opt->h_size = 2000;
+       opt->v_size = 1088;
+       id = ri_get_capable_video_category_id(opt);
+       EXPECT_EQ(id, expected_result);
+
+       opt->h_size = 4096;
+       opt->v_size = 2160;
+       id = ri_get_capable_video_category_id(opt);
+       EXPECT_EQ(id, expected_result);
+
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_mpeg1)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_mpeg1 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P, player->GetCapableVideoCategory("MPEG1", 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_60P, player->GetCapableVideoCategory("MPEG1", 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG1", 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG1", 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG1", 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_mpeg1 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_mpeg2)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_mpeg2 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_30P, player->GetCapableVideoCategory("MPEG2", 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG2_FHD_8BIT_60P, player->GetCapableVideoCategory("MPEG2", 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG2", 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG2", 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG2", 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_mpeg2 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_mpeg4)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_mpeg4 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, player->GetCapableVideoCategory("MPEG4", 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_60P, player->GetCapableVideoCategory("MPEG4", 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG4", 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG4", 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory("MPEG4", 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_mpeg4 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_h263)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_h263 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_H263, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_H263_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_H263, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_H263, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_H263, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_H263, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_h263 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_vp8)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_vp8 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP8_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_VP8, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_vp8 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_vp9)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_vp9 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_UHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_FHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_VP9_UHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_VP9, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_vp9 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_rv)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_rv start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_RV_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_RV, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_rv end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_wmv)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_wmv start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_WMV9_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_WMV, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_wmv end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_avs)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_avs start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_avs end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_avs_plus)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_avs_plus start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AVS_PLUS_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AVS_PLUS, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_avs_plus end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_av1)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_av1 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+
+       if (is_support_av1_120p())
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_8BIT_120P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 120));
+       else
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 10, RI_SAMPLING_FORMAT_OTHERS, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 10, RI_SAMPLING_FORMAT_OTHERS, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_OTHERS, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_OTHERS, 60));
+
+       if (is_support_av1_120p())
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 120));
+       else
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_OTHERS, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 60));
+
+       if (is_support_av1_120p())
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 120));
+       else
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 10, RI_SAMPLING_FORMAT_422, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_FHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 1920, 1080, 10, RI_SAMPLING_FORMAT_422, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+
+       if (is_support_av1_120p())
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_UHD_10BIT_120P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 120));
+       else
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 120));
+
+       if (is_support_8k()) {
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 120));
+
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_OTHERS, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_OTHERS, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_OTHERS, 120));
+
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 120));
+
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_8K_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 120));
+       } else {
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 120));
+
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_OTHERS, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_OTHERS, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 8, RI_SAMPLING_FORMAT_OTHERS, 120));
+
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 120));
+
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 30));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 60));
+               EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 120));
+       }
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_av1 end...");
+}
+
+TEST(ut_rm_api, ri_get_capable_video_category_id_av1_vr360)
+{
+       RM_TEST_MSG("ri_get_capable_video_category_id_av1_vr360 start...");
+
+       TCPlayer *player = new TCPlayer();
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 8, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_8BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 8, RI_SAMPLING_FORMAT_420, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 10, RI_SAMPLING_FORMAT_OTHERS, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 10, RI_SAMPLING_FORMAT_OTHERS, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_OTHERS, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_OTHERS, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_OTHERS, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_FHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 10, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_30P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_AV1_VR360_UHD_10BIT_60P, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_420, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 10, RI_SAMPLING_FORMAT_422, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 1920, 1080, 10, RI_SAMPLING_FORMAT_422, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 3840, 2160, 10, RI_SAMPLING_FORMAT_422, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 8, RI_SAMPLING_FORMAT_420, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 8, RI_SAMPLING_FORMAT_OTHERS, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 8, RI_SAMPLING_FORMAT_OTHERS, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 8, RI_SAMPLING_FORMAT_OTHERS, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 10, RI_SAMPLING_FORMAT_420, 120));
+
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 30));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 60));
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED, player->GetCapableVideoCategory(RI_CODEC_NAME_AV1_VR360, 7680, 4320, 10, RI_SAMPLING_FORMAT_422, 120));
+
+       delete player;
+       RM_TEST_MSG("ri_get_capable_video_category_id_av1_vr360 end...");
+}
+
+
+static rm_cb_result callback_default(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       rm_deallocate_resources(handle, info);
+
+       return RM_CB_RESULT_OK;
+}
+
+TEST(ut_rm_api, allocate_audio_decoder)
+{
+       conflicted = 0;
+       num_of_dealloc_rsc = 0;
+
+       //consumer#1
+       int handle1 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb2, NULL, &handle1, NULL));
+
+       //alloc
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 1;
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request->category_option[0] = 0;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));
+
+       //unregister
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, allocate_audio_decoder_not_supported)
+{
+       conflicted = 0;
+       num_of_dealloc_rsc = 0;
+
+       RM_TEST_MSG("allocate_audio_decoder_not_supported begin");
+
+       //consumer#1
+       int handle1 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb2, NULL, &handle1, NULL));
+
+       //alloc
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 1;
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request->category_option[0] = RM_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle1, request, allocated));
+
+       //unregister
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));
+
+       RM_TEST_MSG("allocate_audio_decoder_not_supported end");
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, allocate_failure_reason)
+{
+       conflicted = 0;
+       num_of_dealloc_rsc = 0;
+
+       //consumer#1
+       int handle1 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb2, NULL, &handle1, NULL));
+
+       //alloc
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));
+       memset((void*)request, 0, sizeof(rm_category_request_s));
+
+       request->request_num = 1;
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request->category_option[0] = RM_CATEGORY_AUDIO_DECODER_NOT_SUPPORTED;
+       request->state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle1, request, allocated));
+       EXPECT_EQ(RM_ERR_TYPE_REQUESTED_RESOURCE_DOES_NOT_EXIST, allocated->error_type);
+
+       //unregister
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));
+
+       sleep(RM_TEST_SLEEP_TIME);
+}
+
+TEST(ut_rm_api, alloc_preference_p1)
+{
+       /*
+       * 1. Allocate the following resources with preference mode at once
+       *    RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+       *  -> Alloc only RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P
+       */
+
+       RM_TEST_MSG("alloc_preference_p1 start...");
+
+       conflicted = 0;
+
+       int handle = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       rm_device_return_s return_devices;
+       memset(&return_devices, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 2;
+
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P;
+       request.state[0] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       request.category_id[1] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[1] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P;
+       request.state[1] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+
+       EXPECT_EQ(request.request_num, return_devices.allocated_num);
+       EXPECT_LT(RM_DEVICE_NONE, return_devices.device_id[0]); // RM_DEVICE_NONE < return_devices.device_id[0]
+       EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[1]);
+
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("alloc_preference_p1 end...");
+}
+
+TEST(ut_rm_api, alloc_preference_p2)
+{
+       /*
+       * 1. Allocate the following resources with preference mode at once
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+       *    RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P
+       *  -> Alloc only RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+       */
+
+       RM_TEST_MSG("alloc_preference_p2 start...");
+
+       conflicted = 0;
+
+       int handle = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       rm_device_return_s return_devices;
+       memset(&return_devices, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 2;
+
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P;
+       request.state[0] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       request.category_id[1] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[1] = RM_CATEGORY_VIDEO_DECODER_MPEG1_FHD_8BIT_30P;
+       request.state[1] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+
+       EXPECT_EQ(request.request_num, return_devices.allocated_num);
+
+       if (is_support_4k()) {
+               EXPECT_LT(RM_DEVICE_NONE, return_devices.device_id[0]); // RM_DEVICE_NONE < return_devices.device_id[0]
+               EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[1]);
+       } else {
+               EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[0]);
+               EXPECT_LT(RM_DEVICE_NONE, return_devices.device_id[1]); // RM_DEVICE_NONE < return_devices.device_id[0]
+       }
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("alloc_preference_p2 end...");
+
+}
+
+TEST(ut_rm_api, alloc_preference_p3)
+{
+       /*
+       * 1. Allocate the following resources with preference mode at once
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P
+       *  -> Alloc only RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+       */
+
+       RM_TEST_MSG("alloc_preference_p3 start...");
+
+       conflicted = 0;
+
+       int handle = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       rm_device_return_s return_devices;
+       memset(&return_devices, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 2;
+
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P;
+       request.state[0] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       request.category_id[1] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[1] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P;
+       request.state[1] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       if (is_support_4k()) {
+               EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+               EXPECT_EQ(request.request_num, return_devices.allocated_num);
+               EXPECT_LT(RM_DEVICE_NONE, return_devices.device_id[0]); // RM_DEVICE_NONE < return_devices.device_id[0]
+               EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[1]);
+       } else {
+               EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+               EXPECT_NE(request.request_num, return_devices.allocated_num);
+               EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[0]);
+               EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[1]);
+       }
+
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("alloc_preference_p3 end...");
+
+}
+
+TEST(ut_rm_api, alloc_preference_n1)
+{
+       /*
+       * 1. Allocate the following resources with exclusive mode
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P -> Alloc
+       * 2. Allocate the following resources with preference mode at once
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P
+       *  -> Alloc : Fail
+       */
+
+       if (ri_get_max_video_decoder_num() >= 4)
+               return;
+
+       if (is_oscars_unified_jpeg_decoder())
+               return;
+
+       RM_TEST_MSG("alloc_preference_n1 start...");
+
+       conflicted = 0;
+
+       int handle = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       rm_device_return_s return_devices;
+       memset(&return_devices, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 1;
+
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P;
+       request.state[0] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       if (is_support_4k()) {
+               EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+               EXPECT_EQ(request.request_num, return_devices.allocated_num);
+               EXPECT_LT(RM_DEVICE_NONE, return_devices.device_id[0]); // RM_DEVICE_NONE < return_devices.device_id[0]
+       } else {
+               EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+               EXPECT_NE(request.request_num, return_devices.allocated_num);
+               EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[0]);
+       }
+
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle2 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle2, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+       memset(&return_devices, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 2;
+
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P;
+       request.state[0] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       request.category_id[1] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[1] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P;
+       request.state[1] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle2, &request, &return_devices));
+
+       EXPECT_EQ(0, return_devices.allocated_num);
+       EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[0]);
+       EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[1]);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("alloc_preference_n1 end...");
+
+}
+
+TEST(ut_rm_api, alloc_preference_n2)
+{
+       /*
+       * 1. Allocate the following resources at once
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P with preference mode
+       *    RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P with exclusive mode
+       *  -> Alloc : fail
+       */
+
+       RM_TEST_MSG("alloc_preference_n2 start...");
+
+       conflicted = 0;
+
+       int handle = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       rm_device_return_s return_devices;
+       memset(&return_devices, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 2;
+
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P;
+       request.state[0] = RM_STATE_EXCLUSIVE_PREFERENCE;
+
+       request.category_id[1] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[1] = RM_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_60P;
+       request.state[1] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &return_devices));
+
+       EXPECT_EQ(0, return_devices.allocated_num);
+       EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[0]);
+       EXPECT_EQ(RM_DEVICE_NONE, return_devices.device_id[1]);
+
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       RM_TEST_MSG("alloc_preference_n2 end...");
+
+}
+
+
+
+TEST(ut_rm_api, alloc_audio_dec_with_legacy_method_p1)
+{
+       /*
+       * 1. Allocate an Audio decoder with Legacy method (app_id : app1) -> Alloc : No conflict : Main audio decoder
+       * 2. Allocate an Audio decoder with Legacy method (app_id : app2) -> Alloc : Conflict with handle#1 : Main audio decoder
+       * 3. Allocate an Audio decoder with Legacy method (app_id : app3) -> Alloc : Conflict with handle#2 : Main audio decoder
+       */
+
+       RM_TEST_MSG("alloc_audio_dec_with_legacy_method_p1 start...");
+
+       int handle = 0;
+
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       const char *app_id1 = "app1";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle, (char*) app_id1));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle2 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle2, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       const char *app_id2 = "app2";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*) app_id2));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(1, conflicted);
+       conflicted = 0;
+
+       int handle3 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle3, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       const char *app_id3 = "app3";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*) app_id3));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(1, conflicted);
+       conflicted = 0;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));
+
+       RM_TEST_MSG("alloc_audio_dec_with_legacy_method_p1 end...");
+}
+
+TEST(ut_rm_api, alloc_audio_dec_with_legacy_method_p2)
+{
+       /*
+       * 1. Allocate a sub Audio decoder with Legacy method (app_id : app1) -> Alloc : No conflict : Sub audio decoder
+       * 2. Allocate a sub Audio decoder with Legacy method (app_id : app2) -> Alloc : Conflict with handle#1 : Sub audio decoder
+       * 3. Allocate a sub Audio decoder with Legacy method (app_id : app3) -> Alloc : Conflict with handle#2 : Sub audio decoder
+       */
+
+       RM_TEST_MSG("alloc_audio_dec_with_legacy_method_p2 start...");
+
+       int handle = 0;
+
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       const char *app_id1 = "app1";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle, (char*) app_id1));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle2 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle2, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       const char *app_id2 = "app2";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*) app_id2));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(1, conflicted);
+       conflicted = 0;
+
+       int handle3 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle3, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       const char *app_id3 = "app3";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*) app_id3));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(1, conflicted);
+       conflicted = 0;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));
+
+       RM_TEST_MSG("alloc_audio_dec_with_legacy_method_p2 end...");
+}
+
+TEST(ut_rm_api, alloc_audio_dec_with_legacy_method_p3)
+{
+       /*
+       * 1. Allocate a main Audio decoder with Legacy method (app_id : app1) -> Alloc : No conflict : Main audio decoder
+       * 2. Allocate a sub Audio decoder with Legacy method (app_id : app2) -> Alloc : No conflict : Sub audio decoder
+       * 3. Allocate a main Audio decoder with Legacy method (app_id : app3) -> Alloc : Conflict with handle#1 : Main audio decoder
+       */
+
+       RM_TEST_MSG("alloc_audio_dec_with_legacy_method_p3 start...");
+
+       int handle = 0;
+
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       const char *app_id1 = "app1";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle, (char*) app_id1));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle2 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle2, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       const char *app_id2 = "app2";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*) app_id2));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle3 = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb3, NULL, &handle3, NULL));
+
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       const char *app_id3 = "app3";
+
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*) app_id3));
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &request, &allocated));
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(1, conflicted);
+       conflicted = 0;
+
+       sleep(RM_TEST_SLEEP_TIME);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));
+
+       RM_TEST_MSG("alloc_audio_dec_with_legacy_method_p3 end...");
+}
+
+
+rm_cb_result conflict_cb_count_num_of_conflicts(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       ++conflicted;
+       num_of_dealloc_rsc = info->request_num;
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+static int handle_during_reclaim;
+
+rm_cb_result conflict_cb_normal(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+rm_cb_result conflict_cb_count_trying_to_register(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_normal, NULL, &handle_during_reclaim, NULL));
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+TEST(ut_rm_api, register_consumer_during_reclaim_p1)
+{
+       if (!is_support_4k())
+               return;
+
+       if (ri_get_max_video_decoder_num() >=4)
+               return;
+
+       if (is_oscars_unified_jpeg_decoder())
+               return;
+
+       RM_TEST_MSG("register_consumer_during_reclaim_p1 start...");
+
+       int handle1 = 0;
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_count_trying_to_register, NULL, &handle1, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       ri_video_category_option_request_s option;
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));
+
+       option.codec_name = "VP9";
+       option.color_depth = 8;
+       option.framerate = 30;
+       option.h_size = 3840;
+       option.v_size = 2160;
+       option.sampling_format = RI_SAMPLING_FORMAT_420;
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(&option);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, &request, &allocated));
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, allocated.device_id[0]);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle2 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_normal, NULL, &handle2, NULL));
+
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(&option);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(1, allocated.allocated_num);
+
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, allocated.device_id[0]);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(&option);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle_during_reclaim, &request, &allocated));
+       EXPECT_EQ(1, allocated.allocated_num);
+
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, allocated.device_id[0]);
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));
+       EXPECT_EQ(RM_OK, rm_unregister(handle_during_reclaim));
+
+       handle_during_reclaim = -1;
+       RM_TEST_MSG("register_consumer_during_reclaim_p1 end...");
+}
+
+static int handle_to_unregister;
+
+rm_cb_result conflict_cb_unregister_all_consumers(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       conflicted++;
+       rm_device_request_s rscs;
+       memset(&rscs, 0, sizeof(rm_device_request_s));
+       rscs.request_num = 1;
+       rscs.device_id[0] = RM_DEVICE_AUDIO_MAIN_OUT;
+
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle_to_unregister, &rscs));
+       EXPECT_EQ(RM_OK, rm_unregister(handle_to_unregister));
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       return RM_CB_RESULT_OK;
+}
+
+rm_cb_result conflict_cb_count(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       conflicted++;
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));
+       return RM_CB_RESULT_OK;
+}
+
+TEST(ut_rm_api, unregister_consumer_during_reclaim_p1)
+{
+       if (!is_support_4k())
+               return;
+
+       if (ri_get_max_video_decoder_num() >=4)
+               return;
+
+       if (is_oscars_unified_jpeg_decoder())
+               return;
+
+       RM_TEST_MSG("unregister_consumer_during_reclaim_p1 start...");
+
+       int handle1 = 0;
+       conflicted = 0;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_unregister_all_consumers, NULL, &handle1, NULL));
+
+       rm_category_request_s request;
+       memset(&request, 0, sizeof(rm_category_request_s));
+
+       ri_video_category_option_request_s option;
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));
+
+       option.codec_name = "VP9";
+       option.color_depth = 8;
+       option.framerate = 30;
+       option.h_size = 3840;
+       option.v_size = 2160;
+       option.sampling_format = RI_SAMPLING_FORMAT_420;
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(&option);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, &request, &allocated));
+       EXPECT_EQ(1, allocated.allocated_num);
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, allocated.device_id[0]);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle2 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_count, NULL, &handle2, NULL));
+       handle_to_unregister = handle2;
+
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 1;
+       request.category_id[0] = RM_CATEGORY_AUDIO_MAIN_OUT;
+       request.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));
+       EXPECT_EQ(1, allocated.allocated_num);
+
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, allocated.device_id[0]);
+       EXPECT_EQ(0, conflicted);
+       conflicted = 0;
+
+       int handle3 = 0;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb_normal, NULL, &handle3, NULL));
+
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       request.request_num = 2;
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;
+       request.category_option[0] = ri_get_capable_video_category_id(&option);
+       request.state[0] = RM_STATE_EXCLUSIVE;
+       request.category_id[1] = RM_CATEGORY_AUDIO_MAIN_OUT;
+       request.state[1] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &request, &allocated));
+       EXPECT_EQ(2, allocated.allocated_num);
+       EXPECT_EQ(1, conflicted); // because one of callbacks is not called
+
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, allocated.device_id[0]);
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, allocated.device_id[1]);
+       conflicted = 0;
+
+       EXPECT_NE(RM_OK, rm_unregister(handle1));
+       EXPECT_NE(RM_OK, rm_unregister(handle2));
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));
+
+       handle_to_unregister = -1;
+       RM_TEST_MSG("unregister_consumer_during_reclaim_p1 end...");
+}
+
+TEST(ut_rm_api, ri_category_not_permitted_p1)
+{
+       RM_TEST_MSG("ri_category_not_permitted_p1 start...");
+
+       int handle;
+       EXPECT_EQ(0, rm_register(callback_default, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+
+       req.request_num = 1;
+       req.category_id[0] = RM_CATEGORY_AUDIO_DECODER;
+       req.category_option[0] = RI_CATEGORY_NOT_PERMITTED;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_NE(0, rm_allocate_resources(handle, &req, &allocated));
+       EXPECT_EQ(RM_ERR_TYPE_NOT_PERMITTED, allocated.error_type);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       RM_TEST_MSG("ri_category_not_permitted_p1 end...");
+}
+
+TEST(ut_rm_api, ri_category_not_permitted_p2)
+{
+       RM_TEST_MSG("ri_category_not_permitted_p2 start...");
+
+       int handle;
+       EXPECT_EQ(0, rm_register(callback_default, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+
+       req.request_num = 1;
+       req.category_id[0] = RM_CATEGORY_AUDIO_MAIN_OUT;
+       req.category_option[0] = RI_CATEGORY_NOT_PERMITTED;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_NE(0, rm_allocate_resources(handle, &req, &allocated));
+       EXPECT_EQ(RM_ERR_TYPE_NOT_PERMITTED, allocated.error_type);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       RM_TEST_MSG("ri_category_not_permitted_p2 end...");
+}
+
+TEST(ut_rm_api, ri_category_not_permitted_p3)
+{
+       RM_TEST_MSG("ri_category_not_permitted_p3 start...");
+
+       int handle;
+       EXPECT_EQ(0, rm_register(callback_default, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+
+       req.request_num = 1;
+       req.category_id[0] = RM_CATEGORY_AUDIO_SUB_OUT;
+       req.category_option[0] = RI_CATEGORY_NOT_PERMITTED;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_NE(0, rm_allocate_resources(handle, &req, &allocated));
+       EXPECT_EQ(RM_ERR_TYPE_NOT_PERMITTED, allocated.error_type);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       RM_TEST_MSG("ri_category_not_permitted_p3 end...");
+}
+
+static rm_cb_result callback_pending_5sec(int handle, rm_callback_type event, rm_device_request_s *info, void *data)
+{
+       sleep(5);
+       rm_deallocate_resources(handle, info);
+
+       return RM_CB_RESULT_OK;
+}
+
+static int n_state_checker = 0;
+static gboolean _get_resource_state(gpointer data)
+{
+       rm_resource_state_e state;
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_TUNER, &state));
+       n_state_checker++;
+       RM_TEST_MSG("n_state_checker(%d)", n_state_checker);
+       sleep(1);
+       return (n_state_checker < 5) ? G_SOURCE_CONTINUE:G_SOURCE_REMOVE;
+}
+
+TEST(ut_rm_api, ri_process_dbus_msg_during_conflict_p1)
+{
+       RM_TEST_MSG("ri_process_dbus_msg_during_conflict_p1 start...");
+
+       int handle;
+       EXPECT_EQ(RM_OK, rm_register(callback_pending_5sec, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+
+       req.request_num = 1;
+       req.category_id[0] = RM_CATEGORY_TUNER;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       rm_device_return_s allocated;
+       memset(&allocated, 0, sizeof(rm_device_return_s));
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));
+
+       int handle2;
+       EXPECT_EQ(RM_OK, rm_register(callback_default, NULL, &handle2, NULL));
+
+       n_state_checker = 0;
+       //g_idle_add(_get_resource_state, NULL);
+
+       GMainContext *context = get_callback_thread_context();
+       GSource *idle_source = g_idle_source_new();
+
+       g_source_set_callback(idle_source, _get_resource_state, NULL, NULL);
+       g_source_attach(idle_source, context);
+       g_source_unref(idle_source);
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &req, &allocated));
+       EXPECT_LT(3, n_state_checker);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));
+
+       RM_TEST_MSG("ri_process_dbus_msg_during_conflict_p1 end...");
+}
+
+TEST(ut_rm_api, rm_get_app_id_p1)
+{
+       RM_TEST_MSG("rm_get_app_id_p1 start...");
+
+       int handle;
+       std::string app_id = "org.tizen.viewer";
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle, (char*) app_id.c_str()));
+
+       char *app_id_ret = NULL;
+       EXPECT_EQ(RM_OK, rm_get_app_id(handle, &app_id_ret));
+       EXPECT_STREQ(app_id.c_str(), app_id_ret);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       RM_TEST_MSG("rm_get_app_id_p1 end...");
+}
+
+TEST(ut_rm_api, rm_get_app_id_p2)
+{
+       RM_TEST_MSG("rm_get_app_id_p2 start...");
+
+       int handle;
+       std::string bin_name = "resource-manager-ut";
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       char *app_id_ret = NULL;
+       EXPECT_EQ(RM_OK, rm_get_app_id(handle, &app_id_ret));
+       EXPECT_STREQ(bin_name.c_str(), app_id_ret);
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       RM_TEST_MSG("rm_get_app_id_p2 end...");
+}
+
+TEST(ut_rm_api, rm_get_app_id_n1)
+{
+       RM_TEST_MSG("rm_get_app_id_n1 start...");
+
+       int handle = 78;
+       char *app_id_ret = NULL;
+
+       EXPECT_NE(RM_OK, rm_get_app_id(handle, &app_id_ret));
+
+       RM_TEST_MSG("rm_get_app_id_n1 end...");
+}
+
+TEST(ut_rm_api, rm_allocate_resources_n1)
+{
+       RM_TEST_MSG("rm_get_app_id_n1 start...");
+
+       int handle;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+       rm_device_return_s rscs;
+       memset(&rscs, 0, sizeof(rm_device_return_s));
+
+       req.request_num = 11;
+       req.category_id[0] = RM_CATEGORY_SCALER;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle, &req, &rscs));
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       RM_TEST_MSG("rm_get_app_id_n1 end...");
+}
+
+TEST(ut_rm_api, rm_deallocate_resources_n1)
+{
+       RM_TEST_MSG("rm_deallocate_resources_n1 start...");
+
+       int handle;
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+       rm_device_return_s rscs;
+       memset(&rscs, 0, sizeof(rm_device_return_s));
+
+       req.request_num = 1;
+       req.category_id[0] = RM_CATEGORY_SCALER;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &rscs));
+
+       rm_device_request_s req_rel;
+       memset(&req_rel, 0, sizeof(rm_device_request_s));
+
+       req_rel.request_num = 12;
+       req_rel.device_id[0] = RM_DEVICE_SCALER;
+
+       EXPECT_NE(RM_OK, rm_deallocate_resources(handle, &req_rel));
+
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       RM_TEST_MSG("rm_deallocate_resources_n1 end...");
+}
+
+TEST(ut_rm_api, rm_query_n1)
+{
+       RM_TEST_MSG("rm_query_n1 start...");
+
+       int handle;
+       int result;
+
+       EXPECT_EQ(RM_OK, rm_register(conflict_cb, NULL, &handle, NULL));
+
+       rm_category_request_s req;
+       memset(&req, 0, sizeof(rm_category_request_s));
+
+       req.request_num = 11;
+       req.category_id[0] = RM_CATEGORY_SCALER;
+       req.state[0] = RM_STATE_EXCLUSIVE;
+
+       EXPECT_NE(RM_OK, rm_query(handle, RM_QUERY_ALLOCATION, &req, &result));
+       EXPECT_EQ(RM_OK, rm_unregister(handle));
+
+       RM_TEST_MSG("rm_query_n1 end...");
+}
diff --git a/ut/testcase/ut_tc_8k.cpp b/ut/testcase/ut_tc_8k.cpp
new file mode 100644 (file)
index 0000000..9d8d6e3
--- /dev/null
@@ -0,0 +1,93 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+\r
+/*\r
+ * The test cases for 8K model.\r
+ *  1. 8K model specific features\r
+ */\r
+\r
+TEST(ut_rm_api, dependency_between_8k_jpeg_decoder_and_bg_scaler)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_JPEG_DECODER_8K -> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_SCALER_BG -> Alloc : (No conflict in 8K not supported model, conflict in 8k model)\r
+       */\r
+\r
+       RM_TEST_MSG("dependency_between_8k_jpeg_decoder_and_bg_scaler start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_JPEG_DECODER_8K\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_JPEG_DECODER;\r
+       request.category_option[0] = ri_get_sub_jpeg_category_id("JPEG", 7680, 4320);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, &request, &allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_SCALER_BG\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+       memset(&allocated, 0, sizeof(sizeof(rm_device_return_s)));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_SCALER_BG;\r
+       request.category_option[0] = 0;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       int expected_result = RM_OK; // bg scaler exists in 8k model only\r
+       int expected_conflict = 1; // bg scaler should be conflicted with 8k jpeg decoder\r
+\r
+       EXPECT_EQ(expected_result, rm_allocate_resources(handle2, &request, &allocated));\r
+       EXPECT_EQ(expected_conflict, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("dependency_between_8k_jpeg_decoder_and_bg_scaler end...");\r
+}\r
diff --git a/ut/testcase/ut_tc_interaction_sound.cpp b/ut/testcase/ut_tc_interaction_sound.cpp
new file mode 100644 (file)
index 0000000..760d395
--- /dev/null
@@ -0,0 +1,1211 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_mpeg_InteractionSound)\r
+{\r
+       rm_tc_clear_audio_decoders();\r
+\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG (appid : user1)-> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG (appid : user1)-> Alloc : No conflict\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG (appid : user1)-> Alloc : Conflict with handle#1\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_mpeg_InteractionSound start...");\r
+\r
+       const char *app_id = "user1";\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)app_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*)app_id));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle3, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*)app_id));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_mpeg_InteractionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_mpeg_with_differnt_type_of_resources_InteractionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG (appid : user1)-> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG (appid : user1)-> Alloc : No conflict\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG (appid : user1)-> Alloc : Conflict with handle#1\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_mpeg_with_differnt_type_of_resources_InteractionSound start...");\r
+\r
+       const char *app_id = "user1";\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)app_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*)app_id));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle3, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*)app_id));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_mpeg_with_differnt_type_of_resources_InteractionSound end...");\r
+}\r
+\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_ac3_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_AC3 (appid : user1) -> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_AC3 (appid : user1) -> Alloc : No conflict\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER_AC3 (appid : user1) -> Alloc : Conflict with handle#1\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_ac3_interactionSound start...");\r
+\r
+       const char *app_id = "user1";\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_AC3\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)app_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_AC3;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_AC3\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*)app_id));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_AC3;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_AC3\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle3, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*)app_id));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_AC3;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_ac3_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_ac4_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_AC4 (appid : user1) -> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_AC4 (appid : user1) -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_ac4_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_AC4\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_AC4;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle2, NULL));\r
+\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_AC4;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_ac4_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_trueHD_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_TRUEHD (appid : user1) -> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_TRUEHD (appid : user1) -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_trueHD_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_TRUEHD\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_TRUEHD;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle2, NULL));\r
+\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_TRUEHD;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_trueHD_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_PCM_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_PCM -> Alloc : Alloc (Mixing mode is supported)\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_PCM_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_PCM\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_PCM;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decodallocate_audio_decoder_PCM_interactionSounder_PCM end...");\r
+}\r
+\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_G2Cook_trueHD_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_G2Cook_trueHD_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_G2Cook_trueHD_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_G2Cook_trueHD2_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK -> Alloc (appid : user1) : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK -> Alloc (appid : user1) : No conflict\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER_TRUEHD -> Alloc (appid : user2) : Alloc conflict with consumer#1\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_G2Cook_trueHD2_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *app_id1 = "user1";\r
+       const char *app_id2 = "user2";\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)app_id1));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*) app_id1));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_TRUEHD\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle3, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*)app_id2));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_TRUEHD;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_G2Cook_trueHD2_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_G2Cook_MPEG_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK -> Alloc (appid : user1) : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK -> Alloc (appid : user1) : No conflict\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG -> Alloc (appid : user2) :  Alloc conflict with consumer#1\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_G2Cook_MPEG_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *app_id1 = "user1";\r
+       const char *app_id2 = "user2";\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)app_id1));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*) app_id1));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_AUDIO_CODEC_NAME_MPEG\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle3, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*)app_id2));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_G2Cook_MPEG_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_MPEG_MPEG_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG -> Alloc (appid : user1) : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG -> Alloc (appid : user2) : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_MPEG_MPEG_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *app_id1 = "user1";\r
+       const char *app_id2 = "user2";\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_MPEG\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)app_id1));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_AUDIO_CODEC_NAME_MPEG\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_set_conflict_flag, NULL, &handle3, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle3, (char*)app_id2));\r
+\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_MPEG_MPEG_interactionSound end...");\r
+}\r
+\r
+\r
+TEST(ut_rm_api, allocate_multi_audio_decoders_by_same_consumer1_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#1 -> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_ADPCM with consumer id#1 -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_multi_audio_decoders_by_same_consumer1_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *user_id = "user1";\r
+\r
+       // Allocate two RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)user_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_ADPCM\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_ADPCM;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_multi_audio_decoders_by_same_consumer1_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_multi_audio_decoders_by_same_consumer2_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#1 -> Alloc : No conflict\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#1 -> Alloc : No conflict\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#1 -> Alloc : Fail\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_multi_audio_decoders_by_same_consumer2_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *user_id = "user1";\r
+\r
+       // Allocate two RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)user_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 2;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       request->category_id[1] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[1] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[1] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       //alloc\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_NE(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_multi_audio_decoders_by_same_consumer2_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_reclaim_resource_had_been_allocated_first_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#1 -> Alloc : No conflict -> main audio decoder\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#2 -> Alloc : No conflict -> sub audio decoder\r
+       * 3. Release main audio decoder -> released\r
+       * 4. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#3 -> Alloc : No conflict -> main audio decoder\r
+       * 5. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with consumer id#4 -> Alloc : conflict with handle#2 -> sub audio decoder\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_reclaim_resource_had_been_allocated_first_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *user_id = "user1";\r
+\r
+       // Allocate two RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1, (char*)user_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated->device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK\r
+\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated->device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       // release main audio decoder\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle3, NULL));\r
+\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, request, allocated));\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated->device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       int handle4 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle4, NULL));\r
+\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle4, request, allocated));\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated->device_id[0]);\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle4));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_reclaim_resource_had_been_allocated_first_interactionSound end...");\r
+}\r
+\r
+\r
+TEST(ut_rm_api, allocate_multi_audio_decoders_by_same_consumer_at_once_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate RI_CATEGORY_AUDIO_DECODER_G2COOK and RI_CATEGORY_AUDIO_DECODER_TRUEHD with consumer id#1 at once -> Alloc\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_multi_audio_decoders_by_same_consumer_at_once_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *user_id = "user1";\r
+\r
+       // Allocate RI_CATEGORY_AUDIO_DECODER_G2COOK and RI_CATEGORY_AUDIO_DECODER_TRUEHD at once.\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1,(char*) user_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 2;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_TRUEHD;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->category_id[1] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[1] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[1] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_multi_audio_decoders_by_same_consumer_at_once_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_mixing_not_supported_codec_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate RI_CATEGORY_AUDIO_DECODER_MPEG_H -> Alloc (Mixing is not supported but allocate)\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_mixing_not_supported_codec_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *user_id = "user1";\r
+\r
+       // Allocate RI_CATEGORY_AUDIO_DECODER_MPEG_H\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1,(char*) user_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG_H;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_mixing_not_supported_codec_interactionSound end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_mixing_not_supported_codec2_interactionSound)\r
+{\r
+       /*\r
+       * 1. Allocate RI_CATEGORY_AUDIO_DECODER_G2COOK -> Alloc\r
+       * 2. Allocate RI_CATEGORY_AUDIO_DECODER_MPEG_H -> Alloc conflict with handle#1 (Mixing is not supported)\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_mixing_not_supported_codec2_interactionSound start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+       rm_tc_reset_conflicted_resources_num();\r
+       const char *user_id = "user1";\r
+\r
+       int handle1 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle1,(char*) user_id));\r
+\r
+       rm_category_request_s *request = (rm_category_request_s*) malloc (sizeof(rm_category_request_s));\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s *allocated = (rm_device_return_s*) malloc (sizeof(rm_device_return_s));\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, request, allocated));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle2, (char*) user_id));\r
+\r
+       memset((void*)request, 0, sizeof(rm_category_request_s));\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_MPEG_H;\r
+       opt.mixing_mode = RI_MIXING_MODE_INTERACTION_SOUND;\r
+\r
+       request->request_num = 1;\r
+       request->category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request->category_option[0] = ri_get_capable_audio_category_id(&opt);\r
+       request->state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset((void*)allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, request, allocated));\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_mixing_not_supported_codec2_interactionSound end...");\r
+}
\ No newline at end of file
diff --git a/ut/testcase/ut_tc_multiview.cpp b/ut/testcase/ut_tc_multiview.cpp
new file mode 100644 (file)
index 0000000..740ece1
--- /dev/null
@@ -0,0 +1,691 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <rm_module_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+#include <TCPlayer.h>\r
+\r
+\r
+TEST(ut_rm_api, alloc_main_audio_dec_p1_multiview)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with main option -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("alloc_main_audio_dec_p1_multiview start...");\r
+\r
+       int handle = 0;\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_MULTIVIEW;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request.category_option[0] = ri_get_capable_audio_category_id(&opt) | RM_DEVICE_OPT_MAIN;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_main_audio_dec_p1_multiview end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_sub_audio_dec_p1_multiview)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER_G2COOK with sub option -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("alloc_sub_audio_dec_p1_multiview start...");\r
+\r
+       int handle = 0;\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_audio_category_option_request_s opt;\r
+       memset(&opt, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       opt.codec_name = RI_AUDIO_CODEC_NAME_G2COOK;\r
+       opt.mixing_mode = RI_MIXING_MODE_MULTIVIEW;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;\r
+       request.category_option[0] = ri_get_capable_audio_category_id(&opt) | RM_DEVICE_OPT_SUB;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_sub_audio_dec_p1_multiview end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_three_video_decoders_in_multiview_p1)\r
+{\r
+       rm_tc_clear_video_decoders();\r
+\r
+       RM_TEST_MSG("alloc_three_video_decoders_in_multiview_p1 start...");\r
+\r
+       int handle1 = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "H264";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 2;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = 0;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       request.category_id[1] = RM_CATEGORY_SCALER;\r
+       request.state[1] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, &request, &allocated));\r
+       EXPECT_EQ(2, allocated.allocated_num);\r
+       // The mfc0 shall be allocated first\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_MAIN, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       rm_device_request_s req_rel;\r
+       memset(&req_rel, 0, sizeof(rm_device_request_s));\r
+\r
+       req_rel.request_num = 1;\r
+       req_rel.device_id[0] = allocated.device_id[1];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle1, &req_rel));\r
+\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 2;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       request.category_id[1] = RM_CATEGORY_SCALER_SUB;\r
+       request.state[1] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));\r
+       EXPECT_EQ(2, allocated.allocated_num);\r
+\r
+       // The mfc1 shall be allocated later\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_SUB, allocated.device_id[0]);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated.device_id[1]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated.device_id[1]));\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       int handle3 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle3, NULL));\r
+\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 2;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER_SUB;\r
+       request.category_option[0] = (ri_get_capable_video_category_id(&option) | RM_DEVICE_OPT_SUB);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       request.category_id[1] = RM_CATEGORY_SCALER_SUB;\r
+       request.state[1] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &request, &allocated));\r
+       EXPECT_EQ(2, allocated.allocated_num);\r
+\r
+       // The mfc0 shall be allocated\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_SUB, allocated.device_id[0]);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated.device_id[1]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated.device_id[1]));\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       RM_TEST_MSG("alloc_three_video_decoders_in_multiview_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_audio_decoder_conflict_p2)\r
+{\r
+       RM_TEST_MSG("multiview_audio_decoder_conflict_p2 start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       int handle1;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle1, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request.category_option[0] = (RI_CATEGORY_AUDIO_DECODER_AAC | RM_DEVICE_OPT_MAIN);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       sleep(2);\r
+\r
+       rm_tc_reset_conflict_num();\r
+       int handle2;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;\r
+       request.category_option[0] = 0;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       int handle3;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle3, NULL));\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER_SUB;\r
+       request.category_option[0] = 0;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);\r
+       EXPECT_EQ(1, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       RM_TEST_MSG("multiview_audio_decoder_conflict_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_audio_sub_out_p)\r
+{\r
+       /*\r
+       * 1. Allocate the following resource with handle#1\r
+       *    RM_CATEGORY_AUDIO_SUB_OUT with RM_STATE_EXCLUSIVE -> Alloc\r
+       */\r
+\r
+       RM_TEST_MSG("alloc_audio_sub_out_p start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       rm_device_return_s allocated_devices;\r
+       memset(&allocated_devices, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 1;\r
+\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_SUB_OUT;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated_devices));\r
+\r
+       EXPECT_EQ(1, allocated_devices.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, allocated_devices.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("alloc_audio_sub_out_p end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_audio_sub_out_conflict_1)\r
+{\r
+       /*\r
+       * 1. Allocate the following resource with handle#1\r
+       *    RM_CATEGORY_AUDIO_SUB_OUT with RM_STATE_EXCLUSIVE -> Alloc\r
+       * 2. Allocate the following resource with handle#2\r
+       *    RM_CATEGORY_AUDIO_MAIN_OUT with RM_STATE_EXCLUSIVE -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("alloc_audio_sub_out_conflict_1 start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       rm_device_return_s allocated_devices;\r
+       memset(&allocated_devices, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 1;\r
+\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_SUB_OUT;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated_devices));\r
+\r
+       EXPECT_EQ(1, allocated_devices.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, allocated_devices.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+       memset(&allocated_devices, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_MAIN_OUT;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated_devices));\r
+\r
+       EXPECT_EQ(1, allocated_devices.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, allocated_devices.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("alloc_audio_sub_out_conflict_1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_audio_sub_out_conflict_2)\r
+{\r
+       /*\r
+       * 1. Allocate the following resource with handle#1\r
+       *    RM_CATEGORY_AUDIO_SUB_OUT with RM_STATE_EXCLUSIVE -> Alloc\r
+       * 2. Allocate the following resource with handle#2\r
+       *    RM_CATEGORY_AUDIO_MAIN_OUT with RM_STATE_EXCLUSIVE -> Alloc : No conflict\r
+       */\r
+\r
+       RM_TEST_MSG("alloc_audio_sub_out_conflict_2 start...");\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       rm_device_return_s allocated_devices;\r
+       memset(&allocated_devices, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 1;\r
+\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_SUB_OUT;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated_devices));\r
+\r
+       EXPECT_EQ(1, allocated_devices.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, allocated_devices.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle2, NULL));\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+       memset(&allocated_devices, 0, sizeof(rm_device_return_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_MAIN_OUT;\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated_devices));\r
+\r
+       EXPECT_EQ(1, allocated_devices.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, allocated_devices.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("alloc_audio_sub_out_conflict_2 end...");\r
+}\r
+\r
+\r
+TEST(ut_rm_api, multiview_scaler_to_main_p1)\r
+{\r
+       RM_TEST_MSG("multiview_scaler_to_main_p1 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_SCALER;\r
+       request.category_option[0] = (RM_CATEGORY_SCALER | RM_FORCE_TO_MAIN);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_scaler_to_main_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_scaler_to_main_p2)\r
+{\r
+       RM_TEST_MSG("multiview_scaler_to_main_p2 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_SCALER_SUB;\r
+       request.category_option[0] = (RM_CATEGORY_SCALER_SUB | RM_FORCE_TO_MAIN);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_scaler_to_main_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_scaler_to_sub_p1)\r
+{\r
+       RM_TEST_MSG("multiview_scaler_to_sub_p1 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_SCALER;\r
+       request.category_option[0] = (RM_CATEGORY_SCALER | RM_FORCE_TO_SUB);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_scaler_to_sub_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_audio_out_to_main_p1)\r
+{\r
+       RM_TEST_MSG("multiview_audio_out_to_main_p1 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_MAIN_OUT;\r
+       request.category_option[0] = (RM_CATEGORY_AUDIO_MAIN_OUT | RM_FORCE_TO_MAIN);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, allocated.device_id[0]);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_audio_out_to_main_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_audio_out_to_main_p2)\r
+{\r
+       RM_TEST_MSG("multiview_audio_out_to_main_p2 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_MAIN_OUT;\r
+       request.category_option[0] = (RM_CATEGORY_AUDIO_MAIN_OUT | RM_FORCE_TO_SUB);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, allocated.device_id[0]);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_audio_out_to_main_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_audio_decoder_main_p1)\r
+{\r
+       RM_TEST_MSG("multiview_audio_decoder_main_p1 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request.category_option[0] = (RM_CATEGORY_AUDIO_DECODER | RM_DEVICE_OPT_MAIN | RM_FORCE_TO_MAIN);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, allocated.device_id[0]);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_audio_decoder_main_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, multiview_audio_decoder_main_p2)\r
+{\r
+       RM_TEST_MSG("multiview_audio_decoder_main_p2 start...");\r
+\r
+       int handle = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_AUDIO_DECODER;\r
+       request.category_option[0] = (RM_CATEGORY_AUDIO_DECODER | RM_DEVICE_OPT_SUB | RM_FORCE_TO_SUB);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, allocated.device_id[0]);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("multiview_audio_decoder_main_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_active_audio_out_p1)\r
+{\r
+       RM_TEST_MSG("rm_active_audio_out_p1 start...");\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+\r
+       EXPECT_EQ(RM_AUDIO_OUT_NONE, player->GetActiveAudioOut());\r
+\r
+       // Allocate audio main out\r
+       player->AddResource(RM_CATEGORY_AUDIO_MAIN_OUT, RM_STATE_EXCLUSIVE);\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+       EXPECT_EQ(RM_AUDIO_OUT_MAIN, player->GetActiveAudioOut());\r
+\r
+       // Allocate audio sub out\r
+       player->RemoveResources();\r
+       player->AddResource(RM_CATEGORY_AUDIO_SUB_OUT, RM_STATE_EXCLUSIVE);\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+       EXPECT_EQ((RM_AUDIO_OUT_MAIN | RM_AUDIO_OUT_SUB), player->GetActiveAudioOut());\r
+\r
+       // Release audio main & sub out\r
+       player->RemoveResources();\r
+       EXPECT_EQ(RM_OK, player->ReleaseResources());\r
+       EXPECT_EQ(RM_AUDIO_OUT_NONE, player->GetActiveAudioOut());\r
+\r
+       // Allocate audio sub out\r
+       player->AddResource(RM_CATEGORY_AUDIO_SUB_OUT, RM_STATE_EXCLUSIVE);\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+       EXPECT_EQ(RM_AUDIO_OUT_SUB, player->GetActiveAudioOut());\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       delete player;\r
+\r
+       RM_TEST_MSG("rm_active_audio_out_p1 end...");\r
+}\r
diff --git a/ut/testcase/ut_tc_multiview_not_support.cpp b/ut/testcase/ut_tc_multiview_not_support.cpp
new file mode 100644 (file)
index 0000000..2d47a14
--- /dev/null
@@ -0,0 +1,158 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+#include <TCPlayer.h>\r
+\r
+TEST(ut_rm_api, alloc_audio_dec_in_mixing_not_supported_model_p1)\r
+{\r
+       /*\r
+       * 1. Allocate an Audio decoder with MultiView mixing mode in mixing not supported model (app_id : app1) -> Alloc : No conflict : Main audio decoder\r
+       * 2. Allocate an Audio decoder with MultiView mixing mode in mixing not supported model (app_id : app2) -> Alloc : conflict with player1: Main audio decoder\r
+       * 3. Allocate a sub Audio decoder with MultiView mixing mode in mixing not supported model (app_id : app3) -> Alloc : No conflict : Sub audio decoder\r
+       * 4. Allocate a sub Audio decoder with MultiView mixing mode in mixing not supported model (app_id : app4) -> Alloc : conflict with player3 : Sub audio decoder\r
+       */\r
+\r
+       RM_TEST_MSG("alloc_audio_dec_in_mixing_not_supported_model_p1 start...");\r
+\r
+       ri_audio_category_option_request_s audio_option;\r
+       memset(&audio_option, 0, sizeof(ri_audio_category_option_request_s));\r
+\r
+       // player1\r
+       audio_option.codec_name = RI_AUDIO_CODEC_NAME_MPEG;\r
+       audio_option.mixing_mode = RI_MIXING_MODE_MULTIVIEW;\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_AUDIO_DECODER, (ri_get_capable_audio_category_id(&audio_option) | RM_DEVICE_OPT_MAIN), RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, player->GetAllocatedResourceId(1));\r
+\r
+       // player2\r
+       TCPlayer *player2 = new TCPlayer();\r
+       player2->AddResource(RM_CATEGORY_AUDIO_DECODER, ri_get_capable_audio_category_id(&audio_option), RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player2->Register());\r
+       EXPECT_EQ(RM_OK, player2->AllocateResources());\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, player2->GetAllocatedResourceId(1));\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+\r
+       // player3\r
+       TCPlayer *player3 = new TCPlayer();\r
+       player3->AddResource(RM_CATEGORY_AUDIO_DECODER_SUB, (ri_get_capable_audio_category_id(&audio_option) | RM_DEVICE_OPT_SUB), RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player3->Register());\r
+       EXPECT_EQ(RM_OK, player3->AllocateResources());\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, player3->GetAllocatedResourceId(1));\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(0, player2->GetConflictNum());\r
+\r
+       // player4\r
+       TCPlayer *player4 = new TCPlayer();\r
+       player4->AddResource(RM_CATEGORY_AUDIO_DECODER_SUB, ri_get_capable_audio_category_id(&audio_option), RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player4->Register());\r
+       EXPECT_EQ(RM_OK, player4->AllocateResources());\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER_SUB, player4->GetAllocatedResourceId(1));\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(0, player2->GetConflictNum());\r
+       EXPECT_EQ(1, player3->GetConflictNum());\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       EXPECT_EQ(RM_OK, player2->Unregister());\r
+       EXPECT_EQ(RM_OK, player3->Unregister());\r
+       EXPECT_EQ(RM_OK, player4->Unregister());\r
+\r
+       delete player;\r
+       delete player2;\r
+       delete player3;\r
+       delete player4;\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("alloc_audio_dec_in_mixing_not_supported_model_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, allocate_audio_decoder_with_legacy_one_not_support_multiview)\r
+{\r
+       /*\r
+       * 1. Allocate a RI_CATEGORY_AUDIO_DECODER -> Alloc : No conflict  -> audio main decoder\r
+       * 2. Allocate a RI_CATEGORY_AUDIO_DECODER_WMA -> Alloc : conflict with Consumer#1  -> audio main decoder\r
+       * 3. Allocate a RI_CATEGORY_AUDIO_DECODER -> Alloc : conflict with Consumer#2 -> audio main decoder\r
+       */\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_with_legacy_one_not_support_multiview start...");\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_AUDIO_DECODER, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->SetAppId("user1"));\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, player->GetAllocatedResourceId(1));\r
+\r
+       // As a resource of GetAudioCategory(), RI_CATEGORY_NONE shall be returned because audio mixing is not supported\r
+       TCPlayer *player2 = new TCPlayer();\r
+       player2->AddResource(RM_CATEGORY_AUDIO_DECODER, player2->GetAudioCategory(RI_AUDIO_CODEC_NAME_WMA, 0), RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player2->Register());\r
+       EXPECT_EQ(RM_OK, player2->SetAppId("user2"));\r
+       EXPECT_EQ(RM_OK, player2->AllocateResources());\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, player2->GetAllocatedResourceId(1));\r
+\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+\r
+       TCPlayer *player3 = new TCPlayer();\r
+       player3->AddResource(RM_CATEGORY_AUDIO_DECODER, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player3->Register());\r
+       EXPECT_EQ(RM_OK, player3->SetAppId("user3"));\r
+       EXPECT_EQ(RM_OK, player3->AllocateResources());\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, player3->GetAllocatedResourceId(1));\r
+\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(1, player2->GetConflictNum());\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       EXPECT_EQ(RM_OK, player2->Unregister());\r
+       EXPECT_EQ(RM_OK, player3->Unregister());\r
+\r
+       delete player;\r
+       delete player2;\r
+       delete player3;\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+\r
+       RM_TEST_MSG("allocate_audio_decoder_with_legacy_one_not_support_multiview end...");\r
+}\r
diff --git a/ut/testcase/ut_tc_resource.cpp b/ut/testcase/ut_tc_resource.cpp
new file mode 100644 (file)
index 0000000..f79eb6d
--- /dev/null
@@ -0,0 +1,676 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <rm_module_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+#include <TCPlayer.h>\r
+\r
+\r
+TEST(ut_rm_api, rm_rsc_state_p1)\r
+{\r
+       RM_TEST_MSG("rm_rsc_state_p1 start...");\r
+\r
+       rm_resource_state_e state;\r
+       int ret = rm_get_resource_state(RM_DEVICE_AUDIO_ENCODER, &state);\r
+\r
+       EXPECT_EQ(RM_OK, ret);\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       RM_TEST_MSG("rm_rsc_state_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_state_n1)\r
+{\r
+       RM_TEST_MSG("rm_rsc_state_n1 start...");\r
+\r
+       rm_resource_state_e state;\r
+       int ret = rm_get_resource_state(9999999, &state);\r
+\r
+       EXPECT_NE(RM_OK, ret);\r
+\r
+       RM_TEST_MSG("rm_rsc_state_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_state_n2)\r
+{\r
+       RM_TEST_MSG("rm_rsc_state_n2 start...");\r
+\r
+       rm_resource_state_e state;\r
+       int ret = rm_get_resource_state(-1, &state);\r
+\r
+       EXPECT_NE(RM_OK, ret);\r
+\r
+       RM_TEST_MSG("rm_rsc_state_n2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_state_n3)\r
+{\r
+       RM_TEST_MSG("rm_rsc_state_n2 start...");\r
+\r
+       int ret = rm_get_resource_state(RM_DEVICE_AUDIO_ENCODER, NULL);\r
+\r
+       EXPECT_NE(RM_OK, ret);\r
+\r
+       RM_TEST_MSG("rm_rsc_state_n3 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_get_resource_list_p1)\r
+{\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p1 start...");\r
+\r
+       rm_resource_list_h rsc_list;\r
+       int ret = rm_get_resource_list(RM_CATEGORY_DEMUX, &rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, ret);\r
+\r
+       rm_resource_h resource;\r
+       EXPECT_EQ(6, rm_resource_list_get_count(rsc_list));\r
+\r
+       resource = rm_resource_list_get_first(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX0, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux0", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX1, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux1", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX2, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux2", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX3, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux3", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX4, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux4", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX5, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux5", rm_resource_get_node(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_next(rsc_list));\r
+\r
+       resource = rm_resource_list_get_last(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX5, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux5", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_prev(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX4, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux4", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_prev(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX3, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux3", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_prev(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX2, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux2", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_prev(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX1, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux1", rm_resource_get_node(resource));\r
+\r
+       resource = rm_resource_list_get_prev(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_DEMUX0, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dvb/adapter0/demux0", rm_resource_get_node(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(rsc_list));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_get_resource_list_p2)\r
+{\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p2 start...");\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_SCALER, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, player->GetAllocatedResourceId(1));\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(player->GetAllocatedResourceId(1)));\r
+\r
+       rm_resource_list_h rsc_list;\r
+       int ret = rm_get_resource_list(RM_CATEGORY_SCALER, &rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, ret);\r
+\r
+       rm_resource_h resource;\r
+       EXPECT_EQ(1, rm_resource_list_get_count(rsc_list));\r
+       resource = rm_resource_list_get_first(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dri/card0", rm_resource_get_node(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, rm_resource_get_state(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_next(rsc_list));\r
+\r
+       resource = rm_resource_list_get_last(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dri/card0", rm_resource_get_node(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, rm_resource_get_state(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(rsc_list));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       delete player;\r
+\r
+       ret = rm_get_resource_list(RM_CATEGORY_SCALER, &rsc_list);\r
+       EXPECT_EQ(RM_OK, ret);\r
+\r
+       EXPECT_EQ(1, rm_resource_list_get_count(rsc_list));\r
+       resource = rm_resource_list_get_first(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dri/card0", rm_resource_get_node(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_next(rsc_list));\r
+\r
+       resource = rm_resource_list_get_last(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("/dev/dri/card0", rm_resource_get_node(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(rsc_list));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_get_resource_list_p3)\r
+{\r
+       if (!is_support_audio_dual_decoding())\r
+               return;\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p3 start...");\r
+\r
+       rm_resource_list_h rsc_list;\r
+       int ret = rm_get_resource_list(RM_CATEGORY_AUDIO_SUB_OUT, &rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, ret);\r
+\r
+       rm_resource_h resource;\r
+       EXPECT_EQ(1, rm_resource_list_get_count(rsc_list));\r
+       resource = rm_resource_list_get_first(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(0, rm_resource_list_get_next(rsc_list));\r
+\r
+       resource = rm_resource_list_get_last(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, rm_resource_get_id(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(rsc_list));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p3 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_get_resource_list_p4)\r
+{\r
+       if (!is_support_audio_dual_decoding())\r
+               return;\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p4 start...");\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_AUDIO_SUB_OUT, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->SetAppId("org.tizen.viewer"));\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, player->GetAllocatedResourceId(1));\r
+\r
+       rm_resource_list_h rsc_list;\r
+       int ret = rm_get_resource_list(RM_CATEGORY_AUDIO_SUB_OUT, &rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, ret);\r
+\r
+       rm_resource_h resource;\r
+       EXPECT_EQ(1, rm_resource_list_get_count(rsc_list));\r
+       resource = rm_resource_list_get_first(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, rm_resource_get_id(resource));\r
+       EXPECT_STREQ("org.tizen.viewer", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(0, rm_resource_list_get_next(rsc_list));\r
+\r
+       resource = rm_resource_list_get_last(rsc_list);\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_SUB_OUT, rm_resource_get_id(resource));\r
+\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(rsc_list));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       delete player;\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_p4 end...");\r
+}\r
+\r
+\r
+TEST(ut_rm_api, rm_rsc_get_resource_list_n1)\r
+{\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_n1 start...");\r
+\r
+       rm_resource_list_h rsc_list;\r
+       int ret = rm_get_resource_list((rm_rsc_category_e) -10, &rsc_list);\r
+\r
+       EXPECT_EQ(RM_OK, ret);\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_rsc_get_resource_list_n2)\r
+{\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_n2 start...");\r
+\r
+       int ret = rm_get_resource_list(RM_CATEGORY_DEMUX, NULL);\r
+\r
+       EXPECT_NE(RM_OK, ret);\r
+\r
+       RM_TEST_MSG("rm_rsc_get_resource_list_n2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_get_id_n1)\r
+{\r
+       RM_TEST_MSG("rm_resource_get_id_n1 start...");\r
+       EXPECT_EQ(-1, rm_resource_get_id(NULL));\r
+       RM_TEST_MSG("rm_resource_get_id_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_get_node_n1)\r
+{\r
+       RM_TEST_MSG("rm_resource_get_node_n1 start...");\r
+       EXPECT_EQ(0, rm_resource_get_node(NULL));\r
+       RM_TEST_MSG("rm_resource_get_node_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_list_get_prev_n1)\r
+{\r
+       RM_TEST_MSG("rm_resource_list_get_prev_n1 start...");\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(NULL));\r
+       rm_resource_list_h list = NULL;\r
+       EXPECT_EQ(0, rm_resource_list_get_prev(list));\r
+       RM_TEST_MSG("rm_resource_list_get_prev_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_get_resource_collection_state_p1)\r
+{\r
+       RM_TEST_MSG("rm_get_resource_collection_state_p1 start...");\r
+\r
+       rm_resource_list_h rsc_list = NULL;\r
+\r
+       EXPECT_EQ(0, rm_get_resource_collection_state(RM_RSC_COLLECTION_MAIN, &rsc_list));\r
+\r
+       // MFD0, DVDE0, MAIN SCALER, MAIN AUDIO DECODER, MAIN AUDIO OUT\r
+       EXPECT_EQ(5, rm_resource_list_get_count(rsc_list));\r
+\r
+       rm_resource_h resource = rm_resource_list_get_first(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(RM_CATEGORY_AUDIO_MAIN_OUT, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(RM_CATEGORY_SCALER, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(RM_CATEGORY_AUDIO_DECODER, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_MAIN, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_LE(RM_CATEGORY_VIDEO_DECODER, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_LE(RM_CATEGORY_VIDEO_DECODER_UHD, rm_resource_get_category(resource));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       RM_TEST_MSG("rm_get_resource_collection_state_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_get_resource_collection_state_p2)\r
+{\r
+       RM_TEST_MSG("rm_get_resource_collection_state_p2 start...");\r
+\r
+       int handle = 0;\r
+       const char *app_id = "org.tizen.test";\r
+       EXPECT_EQ(0, rm_register(rm_cb_set_conflict_flag, NULL, &handle, NULL));\r
+       EXPECT_EQ(0, rm_set_app_id(handle, (char*) app_id));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(req));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(allocated));\r
+\r
+       EXPECT_EQ(0, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+\r
+       rm_resource_list_h rsc_list = NULL;\r
+\r
+       EXPECT_EQ(0, rm_get_resource_collection_state(RM_RSC_COLLECTION_MAIN, &rsc_list));\r
+\r
+       // MFD0, DVDE0, MAIN SCALER, MAIN AUDIO DECODER, MAIN AUDIO OUT\r
+       EXPECT_EQ(5, rm_resource_list_get_count(rsc_list));\r
+\r
+       rm_resource_h resource = rm_resource_list_get_first(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_MAIN_OUT, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(RM_CATEGORY_AUDIO_MAIN_OUT, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(handle, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ(app_id, rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(RM_CATEGORY_SCALER, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_AUDIO_DECODER, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_EQ(RM_CATEGORY_AUDIO_DECODER, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_MAIN, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_LE(RM_CATEGORY_VIDEO_DECODER, rm_resource_get_category(resource));\r
+\r
+       resource = rm_resource_list_get_next(rsc_list);\r
+\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_DVDE0, rm_resource_get_id(resource));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(resource));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(resource));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(resource));\r
+       EXPECT_LE(RM_CATEGORY_VIDEO_DECODER_UHD, rm_resource_get_category(resource));\r
+\r
+       rm_free_resource_list(rsc_list);\r
+\r
+       EXPECT_EQ(0, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("rm_get_resource_collection_state_p2 end...");\r
+}\r
+\r
+\r
+static void tc_resource_state_change_cb1(rm_resource_state_h state, void *data)\r
+{\r
+\r
+}\r
+\r
+static void tc_resource_state_change_cb2(rm_resource_state_h state, void *data)\r
+{\r
+\r
+}\r
+\r
+static void tc_resource_state_change_cb3(rm_resource_state_h state, void *data)\r
+{\r
+\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_state_change_p1)\r
+{\r
+       RM_TEST_MSG("rm_resource_state_change_p1 start...");\r
+\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_ERROR, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_ERROR, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb2, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb3, NULL));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb3));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb2));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1));\r
+\r
+       RM_TEST_MSG("rm_resource_state_change_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_state_change_p2)\r
+{\r
+       RM_TEST_MSG("rm_resource_state_change_p2 start...");\r
+\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_SCALER, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_SCALER_BG, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_SCALER_SUB, tc_resource_state_change_cb1, NULL));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER_BG, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER_SUB, tc_resource_state_change_cb1));\r
+\r
+       RM_TEST_MSG("rm_resource_state_change_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_state_change_p3)\r
+{\r
+       RM_TEST_MSG("rm_resource_state_change_p3 start...");\r
+\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER_BG, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER_SUB, tc_resource_state_change_cb1));\r
+\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_SCALER, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_SCALER_BG, tc_resource_state_change_cb1, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_state_change(RM_CATEGORY_SCALER_SUB, tc_resource_state_change_cb1, NULL));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER_BG, tc_resource_state_change_cb1));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_state_change(RM_CATEGORY_SCALER_SUB, tc_resource_state_change_cb1));\r
+\r
+       RM_TEST_MSG("rm_resource_state_change_p3 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_resource_state_change_n1)\r
+{\r
+       RM_TEST_MSG("rm_resource_state_change_n1 start...");\r
+\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_state_change(RM_CATEGORY_CAMERA, NULL));\r
+       EXPECT_EQ(RM_ERROR, rm_subscribe_resource_state_change(RM_CATEGORY_CAMERA, NULL, NULL));\r
+\r
+       RM_TEST_MSG("rm_resource_state_change_n1 end...");\r
+}\r
+\r
+typedef struct{\r
+       char *app_id;\r
+       int consumer_id;\r
+       int device_id;\r
+       int category_id;\r
+} expected_conflict_event;\r
+\r
+void conflict_event_cb(rm_conflict_resource_h resource, void *data)\r
+{\r
+       RM_TEST_MSG("conflict event cb invoked!");\r
+       if (!data)\r
+               return;\r
+\r
+       expected_conflict_event *expected = (expected_conflict_event*) data;\r
+\r
+       EXPECT_EQ(expected->category_id, rm_conflict_get_category_id(resource));\r
+       EXPECT_EQ(expected->device_id, rm_conflict_get_device_id(resource));\r
+       EXPECT_EQ(expected->consumer_id, rm_conflict_get_consumer_id(resource));\r
+       EXPECT_STREQ(expected->app_id, rm_conflict_get_app_id(resource));\r
+}\r
+\r
+void conflict_event_cb2(rm_conflict_resource_h resource, void *data)\r
+{\r
+\r
+}\r
+\r
+TEST(ut_rm_api, rm_conflict_event_cb_p1)\r
+{\r
+       RM_TEST_MSG("rm_conflict_event_cb_p1 start...");\r
+\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_conflict_event(conflict_event_cb, NULL));\r
+       EXPECT_EQ(RM_ERROR, rm_subscribe_resource_conflict_event(conflict_event_cb, NULL));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_conflict_event(conflict_event_cb));\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_conflict_event(conflict_event_cb));\r
+\r
+       RM_TEST_MSG("rm_conflict_event_cb_p1 end...");\r
+}\r
+\r
+\r
+rm_cb_result resource_conflict_cb(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       RM_TEST_MSG("resource conflict cb invoked!");\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+TEST(ut_rm_api, rm_conflict_event_cb_p2)\r
+{\r
+       RM_TEST_MSG("rm_conflict_event_cb_p2 start...");\r
+\r
+       int handle1 = 0;\r
+       rm_consumer_info *consumer_info1 = (rm_consumer_info*) calloc(1, sizeof(rm_consumer_info));\r
+       snprintf(consumer_info1->app_id, 1024, "%s", "org.tizen.rm.test");\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(resource_conflict_cb, NULL, &handle1, consumer_info1));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_JPEG_DECODER;\r
+       request.category_option[0] = ri_get_sub_jpeg_category_id("JPEG", 7680, 4320);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle1, &request, &allocated));\r
+\r
+       expected_conflict_event *expected = (expected_conflict_event*) calloc(1, sizeof(expected_conflict_event));\r
+       expected->app_id = strdup("org.tizen.rm.test");\r
+\r
+       if (use_unified_jpeg_decoder())\r
+               expected->category_id = RM_CATEGORY_JPEG_DECODER_8K;\r
+       else if (is_oscars_unified_jpeg_decoder())\r
+               expected->category_id = RM_CATEGORY_JPEG_DECODER;\r
+       else\r
+               expected->category_id = RM_CATEGORY_JPEG_DECODER_UHD;\r
+\r
+       expected->consumer_id = handle1;\r
+       expected->device_id = allocated.device_id[0];\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_conflict_event(conflict_event_cb, (void*) expected));\r
+\r
+       int handle2 = 0;\r
+       EXPECT_EQ(RM_OK, rm_register(resource_conflict_cb, NULL, &handle2, NULL));\r
+\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_JPEG_DECODER;\r
+       request.category_option[0] = ri_get_sub_jpeg_category_id("JPEG", 7680, 4320);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &request, &allocated));\r
+\r
+       sleep(5);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_conflict_event(conflict_event_cb));\r
+\r
+       free(consumer_info1);\r
+       consumer_info1 = NULL;\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle1));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       RM_TEST_MSG("rm_conflict_event_cb_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_conflict_event_cb_n1)\r
+{\r
+       RM_TEST_MSG("rm_conflict_event_cb_n1 start...");\r
+\r
+       EXPECT_EQ(RM_ERROR, rm_subscribe_resource_conflict_event(NULL, NULL));\r
+       EXPECT_EQ(RM_ERROR, rm_unsubscribe_resource_conflict_event(NULL));\r
+\r
+       RM_TEST_MSG("rm_conflict_event_cb_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_conflict_event_cb_p3)\r
+{\r
+       RM_TEST_MSG("rm_conflict_event_cb_p3 start...");\r
+\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_conflict_event(conflict_event_cb, NULL));\r
+       EXPECT_EQ(RM_OK, rm_subscribe_resource_conflict_event(conflict_event_cb2, NULL));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_conflict_event(conflict_event_cb2));\r
+       EXPECT_EQ(RM_OK, rm_unsubscribe_resource_conflict_event(conflict_event_cb));\r
+\r
+       RM_TEST_MSG("rm_conflict_event_cb_p3 end...");\r
+}\r
diff --git a/ut/testcase/ut_tc_resource_scaler.cpp b/ut/testcase/ut_tc_resource_scaler.cpp
new file mode 100644 (file)
index 0000000..9d6de5e
--- /dev/null
@@ -0,0 +1,253 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <rm_module_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+#include <TCPlayer.h>\r
+\r
+rm_cb_result rsc_conflict_cb(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       RM_TEST_MSG("resource conflict cb invoked!");\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, info));\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+TEST(ut_rm_api, rm_get_scaler_state_p1)\r
+{\r
+       RM_TEST_MSG("rm_get_scaler_state_p1 start...");\r
+\r
+       int handle;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rsc_conflict_cb, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(req));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(allocated));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       rm_resource_list_h scaler_list_h;\r
+       int result = rm_get_scaler_state(&scaler_list_h);\r
+       EXPECT_EQ(RM_OK, result);\r
+\r
+       if (result != RM_OK) {\r
+               RM_TEST_MSG("rm_get_scaler_state_p1 end...");\r
+               rm_free_resource_list(scaler_list_h);\r
+               return;\r
+       }\r
+\r
+       EXPECT_EQ(2, rm_resource_list_get_count(scaler_list_h));\r
+\r
+       // main scaler\r
+       rm_resource_h rsc = rm_resource_list_get_first(scaler_list_h);\r
+       EXPECT_EQ(RM_CATEGORY_SCALER, rm_resource_get_category(rsc));\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(rsc));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(rsc));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(rsc));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(rsc));\r
+\r
+       // sub scaler\r
+       rsc = rm_resource_list_get_next(scaler_list_h);\r
+       EXPECT_EQ(RM_CATEGORY_SCALER_SUB, rm_resource_get_category(rsc));\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_resource_get_id(rsc));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(rsc));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(rsc));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(rsc));\r
+\r
+       rm_free_resource_list(scaler_list_h);\r
+\r
+       RM_TEST_MSG("rm_get_scaler_state_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_get_scaler_state_p2)\r
+{\r
+       RM_TEST_MSG("rm_get_scaler_state_p2 start...");\r
+\r
+       int handle;\r
+       char *app_id1 = (char*) "org.tizen.rsc.test";\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rsc_conflict_cb, NULL, &handle, NULL));\r
+       EXPECT_EQ(RM_OK, rm_set_app_id(handle, app_id1));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(req));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(allocated));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated.device_id[0]));\r
+\r
+\r
+       rm_resource_list_h scaler_list_h;\r
+       int result = rm_get_scaler_state(&scaler_list_h);\r
+       EXPECT_EQ(RM_OK, result);\r
+\r
+       if (result != RM_OK) {\r
+               EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+               rm_free_resource_list(scaler_list_h);\r
+               RM_TEST_MSG("rm_get_scaler_state_p2 end...");\r
+               return;\r
+       }\r
+\r
+       EXPECT_EQ(2, rm_resource_list_get_count(scaler_list_h));\r
+\r
+       // main scaler\r
+       rm_resource_h rsc = rm_resource_list_get_first(scaler_list_h);\r
+       EXPECT_EQ(RM_CATEGORY_SCALER, rm_resource_get_category(rsc));\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_resource_get_id(rsc));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, rm_resource_get_state(rsc));\r
+       EXPECT_EQ(handle, rm_resource_get_consumer(rsc));\r
+       EXPECT_STREQ(app_id1, rm_resource_get_app_id(rsc));\r
+\r
+       // sub scaler\r
+       rsc = rm_resource_list_get_next(scaler_list_h);\r
+       EXPECT_EQ(RM_CATEGORY_SCALER_SUB, rm_resource_get_category(rsc));\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_resource_get_id(rsc));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, rm_resource_get_state(rsc));\r
+       EXPECT_EQ(-1, rm_resource_get_consumer(rsc));\r
+       EXPECT_STREQ("", rm_resource_get_app_id(rsc));\r
+\r
+       rm_free_resource_list(scaler_list_h);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+       RM_TEST_MSG("rm_get_scaler_state_p2 end...");\r
+}\r
+\r
+/* issue : video decoder(mem cluster) conflict & rsc(sub scaler) conflict\r
+ */\r
+TEST(ut_rm_api, rm_conflict11)\r
+{\r
+       RM_TEST_MSG("rm_conflict11 start...");\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);\r
+       player->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       TCPlayer *player2 = new TCPlayer();\r
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);\r
+       player2->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player2->Register());\r
+       EXPECT_EQ(RM_OK, player2->AllocateResources());\r
+\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(2, player->GetConflictedResourcesNum());\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       EXPECT_EQ(RM_OK, player2->Unregister());\r
+\r
+       delete player;\r
+       delete player2;\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+       RM_TEST_MSG("rm_conflict11 end...");\r
+}\r
+\r
+/* issue : rsc(sub scaler) conflict\r
+ */\r
+TEST(ut_rm_api, rm_conflict14)\r
+{\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_DEVICE_OPT_MAIN, RM_STATE_EXCLUSIVE);\r
+       player->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       TCPlayer *player2 = new TCPlayer();\r
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, RM_STATE_EXCLUSIVE);\r
+       player2->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player2->Register());\r
+       EXPECT_EQ(RM_OK, player2->AllocateResources());\r
+\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(1, player->GetConflictedResourcesNum());\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       EXPECT_EQ(RM_OK, player2->Unregister());\r
+\r
+       delete player;\r
+       delete player2;\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+}\r
+\r
+/* issue : rsc(sub scaler) conflict\r
+ */\r
+TEST(ut_rm_api, rm_conflict16)\r
+{\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, RM_STATE_EXCLUSIVE);\r
+       player->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       TCPlayer *player2 = new TCPlayer();\r
+       player2->AddResource(RM_CATEGORY_VIDEO_DECODER, RM_CATEGORY_VIDEO_DECODER_MPEG4_FHD_8BIT_30P, RM_STATE_EXCLUSIVE);\r
+       player2->AddResource(RM_CATEGORY_SCALER_SUB, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player2->Register());\r
+       EXPECT_EQ(RM_OK, player2->AllocateResources());\r
+\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(1, player->GetConflictedResourcesNum());\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       EXPECT_EQ(RM_OK, player2->Unregister());\r
+\r
+       delete player;\r
+       delete player2;\r
+\r
+       sleep(RM_TEST_SLEEP_TIME);\r
+}
\ No newline at end of file
diff --git a/ut/testcase/ut_tc_video_dec_ai.cpp b/ut/testcase/ut_tc_video_dec_ai.cpp
new file mode 100644 (file)
index 0000000..e64d593
--- /dev/null
@@ -0,0 +1,341 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_hevc_fhd_p1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_hevc_fhd_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_ai_decoder_category_id(ri_get_capable_video_category_id(&option));\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+\r
+       int expected = is_support_8k() ? RM_DEVICE_VIDEO_DECODER_HEVC_8K : RM_DEVICE_VIDEO_DECODER_DVDE0;\r
+\r
+       EXPECT_EQ(expected, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_hevc_fhd_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_hevc_uhd_p1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_hevc_uhd_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 3840;\r
+       option.v_size = 2160;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_ai_decoder_category_id(ri_get_capable_video_category_id(&option));\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+\r
+       int expected = is_support_8k() ? RM_DEVICE_VIDEO_DECODER_HEVC_8K : RM_DEVICE_VIDEO_DECODER_DVDE0;\r
+\r
+       EXPECT_EQ(expected, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_hevc_uhd_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_hevc_8k_p1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_hevc_8k_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 60;\r
+       option.h_size = 7680;\r
+       option.v_size = 4320;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       if (is_support_8k()) {\r
+               EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+               EXPECT_EQ(1, allocated.allocated_num);\r
+               EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_HEVC_8K, allocated.device_id[0]);\r
+       } else {\r
+               EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+               EXPECT_EQ(0, allocated.allocated_num);\r
+       }\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_hevc_8k_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_av1_fhd_p1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_av1_fhd_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "AV1";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_ai_decoder_category_id(ri_get_capable_video_category_id(&option));\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+\r
+       int expected = is_support_8k() ? RM_DEVICE_VIDEO_DECODER_HEVC_8K : RM_DEVICE_VIDEO_DECODER_DVDE0;\r
+\r
+       EXPECT_EQ(expected, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_av1_fhd_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_av1_uhd_p1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_av1_uhd_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "AV1";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 3840;\r
+       option.v_size = 2160;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_ai_decoder_category_id(ri_get_capable_video_category_id(&option));\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+\r
+       int expected = is_support_8k() ? RM_DEVICE_VIDEO_DECODER_HEVC_8K : RM_DEVICE_VIDEO_DECODER_DVDE0;\r
+\r
+       EXPECT_EQ(expected, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_av1_uhd_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_av1_8k_p1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_av1_8k_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "AV1";\r
+       option.color_depth = 8;\r
+       option.framerate = 60;\r
+       option.h_size = 7680;\r
+       option.v_size = 4320;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       if (is_support_8k()) {\r
+               EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+               EXPECT_EQ(1, allocated.allocated_num);\r
+               EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_HEVC_8K, allocated.device_id[0]);\r
+       } else {\r
+               EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+               EXPECT_EQ(0, allocated.allocated_num);\r
+       }\r
+\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_av1_8k_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_ai_video_dec_h264_n1)\r
+{\r
+       RM_TEST_MSG("alloc_ai_video_dec_h264_n1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "H264";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_ai_decoder_category_id(ri_get_capable_video_category_id(&option));\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_NE(RM_DEVICE_VIDEO_DECODER_DVDE0, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_ai_video_dec_h264_n1 end...");\r
+}\r
diff --git a/ut/testcase/ut_tc_video_dec_portrait.cpp b/ut/testcase/ut_tc_video_dec_portrait.cpp
new file mode 100644 (file)
index 0000000..ff3a0d1
--- /dev/null
@@ -0,0 +1,91 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <system_info.h>\r
+#include <rm_debug.h>\r
+\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+\r
+TEST(ut_rm_api, video_decoder_portrait_dtv_1080_1920)\r
+{\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 1080;\r
+       option.v_size = 1920; // Max height supported by mfc is 1080\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P , ri_get_capable_video_category_id(&option));\r
+}\r
+\r
+TEST(ut_rm_api, video_decoder_portrait_dtv_720_1280)\r
+{\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 720;\r
+       option.v_size = 1280; // Max height supported by mfc is 1080\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_HEVC_UHD_8BIT_30P , ri_get_capable_video_category_id(&option));\r
+}\r
+\r
+TEST(ut_rm_api, video_decoder_portrait_dtv_480_640)\r
+{\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 480;\r
+       option.v_size = 640; // Max height supported by mfc is 1080\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_HEVC_FHD_8BIT_30P , ri_get_capable_video_category_id(&option));\r
+}\r
+\r
+TEST(ut_rm_api, video_decoder_portrait_dtv_2160_3840)\r
+{\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 2160;\r
+       option.v_size = 3840; // Max height supported by dvde is 2160\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       EXPECT_EQ(RI_CATEGORY_VIDEO_DECODER_NOT_SUPPORTED , ri_get_capable_video_category_id(&option));\r
+}
\ No newline at end of file
diff --git a/ut/testcase/ut_tc_virtual_scaler.cpp b/ut/testcase/ut_tc_virtual_scaler.cpp
new file mode 100644 (file)
index 0000000..26a8676
--- /dev/null
@@ -0,0 +1,632 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <rm_module_api.h>\r
+#include <stdlib.h>\r
+#include <TCPlayer.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+#include <TCCallbackListener.h>\r
+\r
+static int cb_handle = 0;\r
+static int cb_time = 0;\r
+\r
+rm_cb_result _conflict_cb(int handle, rm_callback_type event, rm_device_request_s *info, void *data)\r
+{\r
+       cb_handle = handle;\r
+       cb_time++;\r
+       rm_unregister(handle);\r
+       return RM_CB_RESULT_OK;\r
+}\r
+\r
+void _reset_cb_info(void)\r
+{\r
+       cb_handle = -1;\r
+       cb_time = 0;\r
+}\r
+\r
+int _get_conflict_num(void)\r
+{\r
+       return cb_time;\r
+}\r
+\r
+int _get_conflict_handle(void)\r
+{\r
+       return cb_handle;\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_p1)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_p1 start...");\r
+\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       rm_resource_state_e state;\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       rm_device_request_s req_release;\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_p2)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_p2 start...");\r
+\r
+       // Step#1 Allocate main scaler\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       rm_resource_state_e state;\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#2 Allocate sub scaler\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle2, NULL));\r
+\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER_SUB;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated2;\r
+       memset(&allocated2, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &req, &allocated2));\r
+\r
+       EXPECT_EQ(1, allocated2.allocated_num);\r
+       EXPECT_EQ((RI_VIRTUAL_ID_SCALER + 1), allocated2.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated2.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#3 Release main scaler\r
+       rm_device_request_s req_release;\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       // Step#4 Release sub scaler\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated2.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle2, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_p3)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_p3 start...");\r
+\r
+       // Step#1 Allocate sub scaler\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER_SUB;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       rm_resource_state_e state;\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#2 Allocate main scaler\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle2, NULL));\r
+\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated2;\r
+       memset(&allocated2, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &req, &allocated2));\r
+\r
+       EXPECT_EQ(1, allocated2.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated2.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated2.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#3 Release sub scaler\r
+       rm_device_request_s req_release;\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       // Step#4 Release main scaler\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated2.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle2, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_p3 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_p4)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_p4 start...");\r
+       _reset_cb_info();\r
+\r
+       /* TEST SCENARIO\r
+       *  1. Allocate main scaler\r
+       *  2. Allocate main scaler (conflict with player 1)\r
+       */\r
+\r
+       TCPlayer *player = new TCPlayer();\r
+       player->AddResource(RM_CATEGORY_SCALER, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player->Register());\r
+       EXPECT_EQ(RM_OK, player->AllocateResources());\r
+\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, player->GetAllocatedResourceId(1));\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(player->GetAllocatedResourceId(1)));\r
+\r
+       rm_resource_state_e state;\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       TCPlayer *player2 = new TCPlayer();\r
+       player2->AddResource(RM_CATEGORY_SCALER, RM_STATE_EXCLUSIVE);\r
+\r
+       EXPECT_EQ(RM_OK, player2->Register());\r
+       EXPECT_EQ(RM_OK, player2->AllocateResources());\r
+\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, player2->GetAllocatedResourceId(1));\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(player2->GetAllocatedResourceId(1)));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       EXPECT_EQ(1, player->GetConflictNum());\r
+       EXPECT_EQ(1, player->GetConflictedResourcesNum());\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, player->GetConflictedResourceId(1));\r
+\r
+       EXPECT_NE(RM_OK, player->ReleaseResource(1));\r
+       EXPECT_EQ(RM_OK, player2->ReleaseResource(1));\r
+\r
+       EXPECT_EQ(RM_OK, player->Unregister());\r
+       EXPECT_EQ(RM_OK, player2->Unregister());\r
+\r
+       delete player;\r
+       delete player2;\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_p4 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_swap_p1)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_p1 start...");\r
+\r
+       /************************************************\r
+        * 1. Allocate sub scaler (handle1)\r
+        * 2. Allocate main scaler (handle2)\r
+        * 3. Swap main scaler with sub\r
+        * 4. Release main scaler (handle1)\r
+        * 5. Release sub scaler (handle2)\r
+        *************************************************/\r
+\r
+       // Step#1 Allocate sub scaler\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER_SUB;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       rm_resource_state_e state;\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#2 Allocate main scaler\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle2, NULL));\r
+\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated2;\r
+       memset(&allocated2, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &req, &allocated2));\r
+\r
+       EXPECT_EQ(1, allocated2.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated2.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated2.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#3 Swap main scaler with sub\r
+       EXPECT_EQ(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_SCALER_SUB));\r
+\r
+       // Step#4 Release main scaler\r
+       rm_device_request_s req_release;\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       // Step#5 Release sub scaler\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated2.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle2, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+\r
+       // restore\r
+       EXPECT_EQ(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_SCALER_SUB));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_swap_p2)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_p2 start...");\r
+\r
+       /************************************************\r
+        * 1. Allocate sub scaler (handle1) 10000:sub\r
+        * 2. Allocate main scaler (handle2) 10001:main\r
+        * 3. Swap main scaler with sub : 10000:main 10001:sub\r
+        * 4. Try to allocate main scaler (handle3)\r
+        *    - Conflict with handle1\r
+        * 4. Release main scaler (handle3)\r
+        * 5. Release sub scaler (handle2)\r
+        *************************************************/\r
+\r
+       _reset_cb_info();\r
+\r
+       // Step#1 Allocate sub scaler\r
+       int handle = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s req;\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER_SUB;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &req, &allocated));\r
+\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER_SUB, rm_find_device_id(allocated.device_id[0]));\r
+\r
+       rm_resource_state_e state;\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#2 Allocate main scaler\r
+       int handle2 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle2, NULL));\r
+\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated2;\r
+       memset(&allocated2, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle2, &req, &allocated2));\r
+\r
+       EXPECT_EQ(1, allocated2.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER, allocated2.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated2.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       // Step#3 Swap main scaler with sub\r
+       EXPECT_EQ(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_SCALER_SUB));\r
+\r
+       // Step#4 Try to allocate main scaler (handle3)\r
+       int handle3 = 0;\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(_conflict_cb, NULL, &handle3, NULL));\r
+\r
+       memset(&req, 0, sizeof(rm_category_request_s));\r
+       req.request_num = 1;\r
+       req.category_id[0] = RM_CATEGORY_SCALER;\r
+       req.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated3;\r
+       memset(&allocated3, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle3, &req, &allocated3));\r
+\r
+       sleep(1);\r
+\r
+       EXPECT_EQ(1, allocated3.allocated_num);\r
+       EXPECT_EQ(RI_VIRTUAL_ID_SCALER + 1, allocated3.device_id[0]);\r
+       EXPECT_EQ(RM_DEVICE_SCALER, rm_find_device_id(allocated3.device_id[0]));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_EXCLUSIVE, state);\r
+\r
+       EXPECT_EQ(handle, _get_conflict_handle());\r
+       EXPECT_EQ(1, _get_conflict_num());\r
+\r
+       // Step#5 Release main scaler (handle3)\r
+       rm_device_request_s req_release;\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle3, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       // Step#6 Release sub scaler (handle2)\r
+       memset(&req_release, 0, sizeof(rm_device_request_s));\r
+\r
+       req_release.request_num = 1;\r
+       req_release.device_id[0] = allocated2.device_id[0];\r
+\r
+       EXPECT_EQ(RM_OK, rm_deallocate_resources(handle2, &req_release));\r
+\r
+       EXPECT_EQ(RM_OK, rm_get_resource_state(RM_DEVICE_SCALER_SUB, &state));\r
+       EXPECT_EQ(RM_RSC_STATE_FREE, state);\r
+\r
+       EXPECT_NE(RM_OK, rm_unregister(handle)); // already unregistered by callback\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle2));\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle3));\r
+\r
+       //restore\r
+       EXPECT_EQ(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_SCALER_SUB));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_p2 end...");\r
+}\r
+\r
+\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_swap_n1)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_n1 start...");\r
+\r
+       EXPECT_NE(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_TUNER));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_n1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_virtual_scaler_swap_n2)\r
+{\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_n2 start...");\r
+\r
+       EXPECT_NE(RM_OK, rm_swap_resources(RM_DEVICE_VIDEO_DECODER_MAIN, RM_DEVICE_VIDEO_DECODER_SUB));\r
+\r
+       RM_TEST_MSG("rm_virtual_scaler_swap_n2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_scaler_changed_cb_p1)\r
+{\r
+       RM_TEST_MSG("rm_scaler_changed_cb_p1 start...");\r
+\r
+       TCCallbackListener *listener = new TCCallbackListener();\r
+\r
+       EXPECT_EQ(RM_OK, listener->RegisterScalerStateChangeCb());\r
+       EXPECT_EQ(RM_OK, listener->UnregisterScalerStateChangeCb());\r
+\r
+       delete listener;\r
+\r
+       RM_TEST_MSG("rm_scaler_changed_cb_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, rm_scaler_changed_cb_n1)\r
+{\r
+       RM_TEST_MSG("rm_scaler_changed_cb_n1 start...");\r
+\r
+       TCCallbackListener *listener = new TCCallbackListener();\r
+\r
+       EXPECT_EQ(RM_OK, listener->RegisterScalerStateChangeCb());\r
+       EXPECT_NE(RM_OK, listener->RegisterScalerStateChangeCb());\r
+\r
+       EXPECT_EQ(RM_OK, listener->UnregisterScalerStateChangeCb());\r
+       EXPECT_NE(RM_OK, listener->UnregisterScalerStateChangeCb());\r
+\r
+       delete listener;\r
+\r
+       RM_TEST_MSG("rm_scaler_changed_cb_n1 end...");\r
+}\r
+\r
+int _get_source_id(int device_id)\r
+{\r
+       if (device_id == RM_DEVICE_SCALER)\r
+               return 0;\r
+       if (device_id == RM_DEVICE_SCALER_SUB)\r
+               return 1;\r
+       return 99;\r
+}\r
+\r
+#if 0 // Resource manager server doesn't send a dbus signal (disabled feature)\r
+TEST(ut_rm_api, rm_scaler_changed_cb_p2)\r
+{\r
+       RM_TEST_MSG("rm_scaler_changed_cb_p2 start...");\r
+\r
+       TCCallbackListener *listener = new TCCallbackListener();\r
+\r
+       EXPECT_EQ(RM_OK, listener->RegisterScalerStateChangeCb());\r
+\r
+       EXPECT_EQ(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_SCALER_SUB));\r
+\r
+       sleep(2);\r
+\r
+       EXPECT_EQ(1, listener->GetNotificationNum());\r
+       EXPECT_EQ(1, listener->IsIncluded(RI_VIRTUAL_ID_SCALER + 1, _get_source_id(RM_DEVICE_SCALER)));\r
+       EXPECT_EQ(1, listener->IsIncluded(RI_VIRTUAL_ID_SCALER, _get_source_id(RM_DEVICE_SCALER_SUB)));\r
+\r
+       EXPECT_EQ(RM_OK, rm_swap_resources(RM_DEVICE_SCALER, RM_DEVICE_SCALER_SUB));\r
+\r
+       sleep(2);\r
+\r
+       EXPECT_EQ(2, listener->GetNotificationNum());\r
+       EXPECT_EQ(1, listener->IsIncluded(RI_VIRTUAL_ID_SCALER, _get_source_id(RM_DEVICE_SCALER)));\r
+       EXPECT_EQ(1, listener->IsIncluded(RI_VIRTUAL_ID_SCALER + 1, _get_source_id(RM_DEVICE_SCALER_SUB)));\r
+\r
+       EXPECT_EQ(RM_OK, listener->UnregisterScalerStateChangeCb());\r
+\r
+       delete listener;\r
+\r
+       RM_TEST_MSG("rm_scaler_changed_cb_p2 end...");\r
+}\r
+#endif//0\r
diff --git a/ut/testcase/ut_tc_vr360.cpp b/ut/testcase/ut_tc_vr360.cpp
new file mode 100644 (file)
index 0000000..a4ca039
--- /dev/null
@@ -0,0 +1,242 @@
+/*\r
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd All Rights Reserved\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ * http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ */\r
+\r
+#include "gtest/gtest.h"\r
+#include <unistd.h>\r
+\r
+#include <rm_api.h>\r
+#include <stdlib.h>\r
+#include <ri-api.h>\r
+#include <ri-module-api.h>\r
+#include <rm_debug.h>\r
+#include <dlog.h>\r
+#include <sys/stat.h>\r
+#include <sys/ipc.h>\r
+#include <sys/msg.h>\r
+\r
+#include <ut_common.h>\r
+\r
+TEST(ut_rm_api, alloc_video_dec_av1_vr360_p1)\r
+{\r
+       RM_TEST_MSG("alloc_video_dec_av1_vr360_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "AV1_VR360";\r
+       option.color_depth = 8;\r
+       option.framerate = 30;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_VR360DEC, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_video_dec_av1_vr360_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_video_dec_av1_vr360_p2)\r
+{\r
+       RM_TEST_MSG("alloc_video_dec_av1_vr360_p2 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "AV1_VR360";\r
+       option.color_depth = 8;\r
+       option.framerate = 60;\r
+       option.h_size = 3840;\r
+       option.v_size = 2160;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       if (is_support_4k()) {\r
+               EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+               EXPECT_EQ(1, allocated.allocated_num);\r
+               EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_VR360DEC, allocated.device_id[0]);\r
+               EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       } else {\r
+               EXPECT_NE(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+               EXPECT_EQ(0, allocated.allocated_num);\r
+               EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       }\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_video_dec_av1_vr360_p2 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_video_dec_h264_vr360_p1)\r
+{\r
+       RM_TEST_MSG("alloc_video_dec_h264_vr360_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "H264_VR360";\r
+       option.color_depth = 8;\r
+       option.framerate = 60;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_VR360DEC, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_video_dec_h264_vr360_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_video_dec_vp9_vr360_p1)\r
+{\r
+       RM_TEST_MSG("alloc_video_dec_vp9_vr360_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "VP9_VR360";\r
+       option.color_depth = 8;\r
+       option.framerate = 60;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_VR360DEC, allocated.device_id[0]);\r
+       EXPECT_STREQ("OMX.SDP.video_decoder.vr360dec", allocated.omx_comp_name[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_video_dec_vp9_vr360_p1 end...");\r
+}\r
+\r
+TEST(ut_rm_api, alloc_video_dec_hevc_vr360_p1)\r
+{\r
+       RM_TEST_MSG("alloc_video_dec_hevc_vr360_p1 start...");\r
+\r
+       int handle = 0;\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_register(rm_cb_counting_conflicted, NULL, &handle, NULL));\r
+\r
+       rm_category_request_s request;\r
+       memset(&request, 0, sizeof(rm_category_request_s));\r
+\r
+       ri_video_category_option_request_s option;\r
+       memset(&option, 0, sizeof(ri_video_category_option_request_s));\r
+\r
+       option.codec_name = "HEVC_VR360";\r
+       option.color_depth = 8;\r
+       option.framerate = 60;\r
+       option.h_size = 1920;\r
+       option.v_size = 1080;\r
+       option.sampling_format = RI_SAMPLING_FORMAT_420;\r
+\r
+       request.request_num = 1;\r
+       request.category_id[0] = RM_CATEGORY_VIDEO_DECODER;\r
+       request.category_option[0] = ri_get_capable_video_category_id(&option);\r
+       request.state[0] = RM_STATE_EXCLUSIVE;\r
+\r
+       rm_device_return_s allocated;\r
+       memset(&allocated, 0, sizeof(rm_device_return_s));\r
+\r
+       EXPECT_EQ(RM_OK, rm_allocate_resources(handle, &request, &allocated));\r
+       EXPECT_EQ(1, allocated.allocated_num);\r
+       EXPECT_EQ(RM_DEVICE_VIDEO_DECODER_VR360DEC, allocated.device_id[0]);\r
+       EXPECT_EQ(0, rm_tc_get_conflict_num());\r
+       rm_tc_reset_conflict_num();\r
+\r
+       EXPECT_EQ(RM_OK, rm_unregister(handle));\r
+\r
+       RM_TEST_MSG("alloc_video_dec_hevc_vr360_p1 end...");\r
+}\r