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 #ifndef MEDIA_STAGEFRIGHT_XMLPARSER_H_
18 #define MEDIA_STAGEFRIGHT_XMLPARSER_H_
19 
20 #include <sys/types.h>
21 #include <utils/Errors.h>
22 #include <utils/Vector.h>
23 #include <utils/StrongPointer.h>
24 
25 #include <string>
26 #include <set>
27 #include <map>
28 #include <vector>
29 
30 namespace android {
31 
32 class MediaCodecsXmlParser {
33 public:
34 
35     // Treblized media codec list will be located in /odm/etc or /vendor/etc.
36     static constexpr char const* defaultSearchDirs[] =
37             {"/odm/etc", "/vendor/etc", "/etc", nullptr};
38     static constexpr char const* defaultMainXmlName =
39             "media_codecs.xml";
40     static constexpr char const* defaultPerformanceXmlName =
41             "media_codecs_performance.xml";
42     static constexpr char const* defaultProfilingResultsXmlPath =
43             "/data/misc/media/media_codecs_profiling_results.xml";
44 
45     MediaCodecsXmlParser(
46             const char* const* searchDirs = defaultSearchDirs,
47             const char* mainXmlName = defaultMainXmlName,
48             const char* performanceXmlName = defaultPerformanceXmlName,
49             const char* profilingResultsXmlPath = defaultProfilingResultsXmlPath);
50     ~MediaCodecsXmlParser();
51 
52     typedef std::pair<std::string, std::string> Attribute;
53     typedef std::map<std::string, std::string> AttributeMap;
54 
55     typedef std::pair<std::string, AttributeMap> Type;
56     typedef std::map<std::string, AttributeMap> TypeMap;
57 
58     typedef std::set<std::string> QuirkSet;
59 
60     /**
61      * Properties of a codec (node)
62      */
63     struct CodecProperties {
64         bool isEncoder;    ///< Whether this codec is an encoder or a decoder
65         size_t order;      ///< Order of appearance in the file (starting from 0)
66         QuirkSet quirkSet; ///< Set of quirks requested by this codec
67         TypeMap typeMap;   ///< Map of types supported by this codec
68     };
69 
70     typedef std::pair<std::string, CodecProperties> Codec;
71     typedef std::map<std::string, CodecProperties> CodecMap;
72 
73     /**
74      * Properties of a node (for IOmxStore)
75      */
76     struct NodeInfo {
77         std::string name;
78         std::vector<Attribute> attributeList;
79     };
80 
81     /**
82      * Properties of a role (for IOmxStore)
83      */
84     struct RoleProperties {
85         std::string type;
86         bool isEncoder;
87         std::multimap<size_t, NodeInfo> nodeList;
88     };
89 
90     typedef std::pair<std::string, RoleProperties> Role;
91     typedef std::map<std::string, RoleProperties> RoleMap;
92 
93     /**
94      * Return a map for attributes that are service-specific.
95      */
96     const AttributeMap& getServiceAttributeMap() const;
97 
98     /**
99      * Return a map for codecs and their properties.
100      */
101     const CodecMap& getCodecMap() const;
102 
103     /**
104      * Return a map for roles and their properties.
105      * This map is generated from the CodecMap.
106      */
107     const RoleMap& getRoleMap() const;
108 
109     /**
110      * Return a common prefix of all node names.
111      *
112      * The prefix is not provided in the xml, so it has to be computed by taking
113      * the longest common prefix of all node names.
114      */
115     const char* getCommonPrefix() const;
116 
117     status_t getParsingStatus() const;
118 
119 private:
120     enum Section {
121         SECTION_TOPLEVEL,
122         SECTION_SETTINGS,
123         SECTION_DECODERS,
124         SECTION_DECODER,
125         SECTION_DECODER_TYPE,
126         SECTION_ENCODERS,
127         SECTION_ENCODER,
128         SECTION_ENCODER_TYPE,
129         SECTION_INCLUDE,
130     };
131 
132     status_t mParsingStatus;
133     Section mCurrentSection;
134     bool mUpdate;
135     std::vector<Section> mSectionStack;
136     std::string mHrefBase;
137 
138     // Service attributes
139     AttributeMap mServiceAttributeMap;
140 
141     // Codec attributes
142     std::string mCurrentName;
143     std::set<std::string> mCodecSet;
144     Codec mCodecListTemp[2048];
145     CodecMap mCodecMap;
146     size_t mCodecCounter;
147     CodecMap::iterator mCurrentCodec;
148     TypeMap::iterator mCurrentType;
149 
150     // Role map
151     mutable RoleMap mRoleMap;
152 
153     // Computed longest common prefix
154     mutable std::string mCommonPrefix;
155 
156     bool parseTopLevelXMLFile(const char *path, bool ignore_errors = false);
157 
158     void parseXMLFile(const char *path);
159 
160     static void StartElementHandlerWrapper(
161             void *me, const char *name, const char **attrs);
162 
163     static void EndElementHandlerWrapper(void *me, const char *name);
164 
165     void startElementHandler(const char *name, const char **attrs);
166     void endElementHandler(const char *name);
167 
168     status_t includeXMLFile(const char **attrs);
169     status_t addSettingFromAttributes(const char **attrs);
170     status_t addMediaCodecFromAttributes(bool encoder, const char **attrs);
171     void addMediaCodec(bool encoder, const char *name,
172             const char *type = nullptr);
173 
174     status_t addQuirk(const char **attrs);
175     status_t addTypeFromAttributes(const char **attrs, bool encoder);
176     status_t addLimit(const char **attrs);
177     status_t addFeature(const char **attrs);
178     void addType(const char *name);
179 
180     void generateRoleMap() const;
181     void generateCommonPrefix() const;
182 
183     MediaCodecsXmlParser(const MediaCodecsXmlParser&) = delete;
184     MediaCodecsXmlParser& operator=(const MediaCodecsXmlParser&) = delete;
185 };
186 
187 } // namespace android
188 
189 #endif // MEDIA_STAGEFRIGHT_XMLPARSER_H_
190 
191