1 /*
2 * Copyright 2017, The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <ios>
18 #include <list>
19
20 #define LOG_TAG "OmxStore"
21
22 #include <android-base/logging.h>
23
24 #include <media/stagefright/omx/1.0/Conversion.h>
25 #include <media/stagefright/omx/1.0/OmxStore.h>
26 #include <media/stagefright/xmlparser/MediaCodecsXmlParser.h>
27
28 namespace android {
29 namespace hardware {
30 namespace media {
31 namespace omx {
32 namespace V1_0 {
33 namespace implementation {
34
35 using ::android::hardware::media::omx::V1_0::Status;
36 using ::android::hardware::media::omx::V1_0::IOmx;
37
OmxStore(const sp<IOmx> & omx,const char * owner,const std::vector<std::string> & searchDirs,const std::vector<std::string> & xmlNames,const char * profilingResultsXmlPath)38 OmxStore::OmxStore(
39 const sp<IOmx> &omx,
40 const char* owner,
41 const std::vector<std::string> &searchDirs,
42 const std::vector<std::string> &xmlNames,
43 const char* profilingResultsXmlPath) {
44 // retrieve list of omx nodes
45 std::set<std::string> nodes;
46 if (omx != nullptr) {
47 omx->listNodes([&nodes](const Status &status,
48 const hidl_vec<IOmx::ComponentInfo> &nodeList) {
49 if (status == Status::OK) {
50 for (const IOmx::ComponentInfo& info : nodeList) {
51 nodes.emplace(info.mName.c_str());
52 }
53 }
54 });
55 }
56
57 if (!nodes.empty()) {
58 auto anyNode = nodes.cbegin();
59 std::string::const_iterator first = anyNode->cbegin();
60 std::string::const_iterator last = anyNode->cend();
61 for (const std::string &name : nodes) {
62 std::string::const_iterator it1 = first;
63 for (std::string::const_iterator it2 = name.cbegin();
64 it1 != last && it2 != name.cend() && tolower(*it1) == tolower(*it2);
65 ++it1, ++it2) {
66 }
67 last = it1;
68 }
69 mPrefix = std::string(first, last);
70 LOG(INFO) << "omx common prefix: '" << mPrefix.c_str() << "'";
71 } else {
72 LOG(INFO) << "omx common prefix: no nodes";
73 }
74
75 MediaCodecsXmlParser parser;
76 parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs);
77 if (profilingResultsXmlPath != nullptr) {
78 parser.parseXmlPath(profilingResultsXmlPath);
79 }
80 mParsingStatus = toStatus(parser.getParsingStatus());
81
82 const auto& serviceAttributeMap = parser.getServiceAttributeMap();
83 mServiceAttributeList.resize(serviceAttributeMap.size());
84 size_t i = 0;
85 for (const auto& attributePair : serviceAttributeMap) {
86 ServiceAttribute attribute;
87 attribute.key = attributePair.first;
88 attribute.value = attributePair.second;
89 mServiceAttributeList[i] = std::move(attribute);
90 ++i;
91 }
92
93 const auto& roleMap = parser.getRoleMap();
94 mRoleList.resize(roleMap.size());
95 i = 0;
96 for (const auto& rolePair : roleMap) {
97 RoleInfo role;
98 role.role = rolePair.first;
99 role.type = rolePair.second.type;
100 role.isEncoder = rolePair.second.isEncoder;
101 role.preferPlatformNodes = false; // deprecated and ignored, using rank instead
102 hidl_vec<NodeInfo>& nodeList = role.nodes;
103 nodeList.resize(rolePair.second.nodeList.size());
104 size_t j = 0;
105 for (const auto& nodePair : rolePair.second.nodeList) {
106 if (!nodes.count(nodePair.second.name)) {
107 // not supported by this OMX instance
108 if (!strncasecmp(nodePair.second.name.c_str(), "omx.", 4)) {
109 LOG(INFO) << "node [" << nodePair.second.name.c_str() << "] not found in IOmx";
110 }
111 continue;
112 }
113 NodeInfo node;
114 node.name = nodePair.second.name;
115 node.owner = owner;
116 hidl_vec<NodeAttribute>& attributeList = node.attributes;
117 attributeList.resize(nodePair.second.attributeList.size());
118 size_t k = 0;
119 for (const auto& attributePair : nodePair.second.attributeList) {
120 NodeAttribute attribute;
121 attribute.key = attributePair.first;
122 attribute.value = attributePair.second;
123 attributeList[k] = std::move(attribute);
124 ++k;
125 }
126 nodeList[j] = std::move(node);
127 ++j;
128 }
129 nodeList.resize(j);
130 mRoleList[i] = std::move(role);
131 ++i;
132 }
133 }
134
~OmxStore()135 OmxStore::~OmxStore() {
136 }
137
listServiceAttributes(listServiceAttributes_cb _hidl_cb)138 Return<void> OmxStore::listServiceAttributes(listServiceAttributes_cb _hidl_cb) {
139 if (mParsingStatus == Status::NO_ERROR) {
140 _hidl_cb(Status::NO_ERROR, mServiceAttributeList);
141 } else {
142 _hidl_cb(mParsingStatus, hidl_vec<ServiceAttribute>());
143 }
144 return Void();
145 }
146
getNodePrefix(getNodePrefix_cb _hidl_cb)147 Return<void> OmxStore::getNodePrefix(getNodePrefix_cb _hidl_cb) {
148 _hidl_cb(mPrefix);
149 return Void();
150 }
151
listRoles(listRoles_cb _hidl_cb)152 Return<void> OmxStore::listRoles(listRoles_cb _hidl_cb) {
153 _hidl_cb(mRoleList);
154 return Void();
155 }
156
getOmx(hidl_string const & omxName)157 Return<sp<IOmx>> OmxStore::getOmx(hidl_string const& omxName) {
158 return IOmx::tryGetService(omxName);
159 }
160
161 } // namespace implementation
162 } // namespace V1_0
163 } // namespace omx
164 } // namespace media
165 } // namespace hardware
166 } // namespace android
167