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
30namespace android {
31
32class MediaCodecsXmlParser {
33public:
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
119private:
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