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     MediaCodecsXmlParser parser;
58     parser.parseXmlFilesInSearchDirs(xmlNames, searchDirs);
59     if (profilingResultsXmlPath != nullptr) {
60         parser.parseXmlPath(profilingResultsXmlPath);
61     }
62     mParsingStatus = toStatus(parser.getParsingStatus());
63 
64     const auto& serviceAttributeMap = parser.getServiceAttributeMap();
65     mServiceAttributeList.resize(serviceAttributeMap.size());
66     size_t i = 0;
67     for (const auto& attributePair : serviceAttributeMap) {
68         ServiceAttribute attribute;
69         attribute.key = attributePair.first;
70         attribute.value = attributePair.second;
71         mServiceAttributeList[i] = std::move(attribute);
72         ++i;
73     }
74 
75     const auto& roleMap = parser.getRoleMap();
76     mRoleList.resize(roleMap.size());
77     i = 0;
78     for (const auto& rolePair : roleMap) {
79         RoleInfo role;
80         role.role = rolePair.first;
81         role.type = rolePair.second.type;
82         role.isEncoder = rolePair.second.isEncoder;
83         role.preferPlatformNodes = false; // deprecated and ignored, using rank instead
84         hidl_vec<NodeInfo>& nodeList = role.nodes;
85         nodeList.resize(rolePair.second.nodeList.size());
86         size_t j = 0;
87         for (const auto& nodePair : rolePair.second.nodeList) {
88             if (!nodes.count(nodePair.second.name)) {
89                 // not supported by this OMX instance
90                 if (!strncasecmp(nodePair.second.name.c_str(), "omx.", 4)) {
91                     LOG(INFO) << "node [" << nodePair.second.name.c_str() << "] not found in IOmx";
92                 }
93                 continue;
94             }
95             NodeInfo node;
96             node.name = nodePair.second.name;
97             node.owner = owner;
98             hidl_vec<NodeAttribute>& attributeList = node.attributes;
99             attributeList.resize(nodePair.second.attributeList.size());
100             size_t k = 0;
101             for (const auto& attributePair : nodePair.second.attributeList) {
102                 NodeAttribute attribute;
103                 attribute.key = attributePair.first;
104                 attribute.value = attributePair.second;
105                 attributeList[k] = std::move(attribute);
106                 ++k;
107             }
108             nodeList[j] = std::move(node);
109             ++j;
110         }
111         nodeList.resize(j);
112         mRoleList[i] = std::move(role);
113         ++i;
114     }
115 
116     mPrefix = parser.getCommonPrefix();
117 }
118 
~OmxStore()119 OmxStore::~OmxStore() {
120 }
121 
listServiceAttributes(listServiceAttributes_cb _hidl_cb)122 Return<void> OmxStore::listServiceAttributes(listServiceAttributes_cb _hidl_cb) {
123     if (mParsingStatus == Status::NO_ERROR) {
124         _hidl_cb(Status::NO_ERROR, mServiceAttributeList);
125     } else {
126         _hidl_cb(mParsingStatus, hidl_vec<ServiceAttribute>());
127     }
128     return Void();
129 }
130 
getNodePrefix(getNodePrefix_cb _hidl_cb)131 Return<void> OmxStore::getNodePrefix(getNodePrefix_cb _hidl_cb) {
132     _hidl_cb(mPrefix);
133     return Void();
134 }
135 
listRoles(listRoles_cb _hidl_cb)136 Return<void> OmxStore::listRoles(listRoles_cb _hidl_cb) {
137     _hidl_cb(mRoleList);
138     return Void();
139 }
140 
getOmx(hidl_string const & omxName)141 Return<sp<IOmx>> OmxStore::getOmx(hidl_string const& omxName) {
142     return IOmx::tryGetService(omxName);
143 }
144 
145 }  // namespace implementation
146 }  // namespace V1_0
147 }  // namespace omx
148 }  // namespace media
149 }  // namespace hardware
150 }  // namespace android
151