1/*
2 * Copyright 2014, 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_CODEC_INFO_H_
18
19#define MEDIA_CODEC_INFO_H_
20
21#include <android-base/macros.h>
22#include <binder/Parcel.h>
23#include <media/stagefright/foundation/ABase.h>
24#include <media/stagefright/foundation/AString.h>
25
26#include <sys/types.h>
27#include <utils/Errors.h>
28#include <utils/KeyedVector.h>
29#include <utils/RefBase.h>
30#include <utils/Vector.h>
31#include <utils/StrongPointer.h>
32
33namespace android {
34
35struct AMessage;
36class Parcel;
37
38typedef KeyedVector<AString, AString> CodecSettings;
39
40struct MediaCodecInfoWriter;
41struct MediaCodecListWriter;
42
43struct MediaCodecInfo : public RefBase {
44    struct ProfileLevel {
45        uint32_t mProfile;
46        uint32_t mLevel;
47        bool operator <(const ProfileLevel &o) const {
48            return mProfile < o.mProfile || (mProfile == o.mProfile && mLevel < o.mLevel);
49        }
50    };
51
52    struct CapabilitiesWriter;
53
54    struct Capabilities : public RefBase {
55        enum {
56            // decoder flags
57            kFlagSupportsAdaptivePlayback = 1 << 0,
58            kFlagSupportsSecurePlayback = 1 << 1,
59            kFlagSupportsTunneledPlayback = 1 << 2,
60
61            // encoder flags
62            kFlagSupportsIntraRefresh = 1 << 0,
63
64        };
65
66        void getSupportedProfileLevels(Vector<ProfileLevel> *profileLevels) const;
67        void getSupportedColorFormats(Vector<uint32_t> *colorFormats) const;
68        uint32_t getFlags() const;
69        const sp<AMessage> getDetails() const;
70
71    protected:
72        Vector<ProfileLevel> mProfileLevels;
73        SortedVector<ProfileLevel> mProfileLevelsSorted;
74        Vector<uint32_t> mColorFormats;
75        SortedVector<uint32_t> mColorFormatsSorted;
76        uint32_t mFlags;
77        sp<AMessage> mDetails;
78
79        Capabilities();
80
81    private:
82        // read object from parcel even if object creation fails
83        static sp<Capabilities> FromParcel(const Parcel &parcel);
84        status_t writeToParcel(Parcel *parcel) const;
85
86        DISALLOW_COPY_AND_ASSIGN(Capabilities);
87
88        friend struct MediaCodecInfo;
89        friend struct MediaCodecInfoWriter;
90        friend struct CapabilitiesWriter;
91    };
92
93    /**
94     * This class is used for modifying information inside a `Capabilities`
95     * object. An object of type `CapabilitiesWriter` can be obtained by calling
96     * `MediaCodecInfoWriter::addMime()` or
97     * `MediaCodecInfoWriter::updateMime()`.
98     */
99    struct CapabilitiesWriter {
100        /**
101         * Add a key-value pair to the list of details. If the key already
102         * exists, the old value will be replaced.
103         *
104         * A pair added by this function will be accessible by
105         * `Capabilities::getDetails()`. Call `AMessage::getString()` with the
106         * same key to retrieve the value.
107         *
108         * @param key The key.
109         * @param value The string value.
110         */
111        void addDetail(const char* key, const char* value);
112        /**
113         * Add a key-value pair to the list of details. If the key already
114         * exists, the old value will be replaced.
115         *
116         * A pair added by this function will be accessible by
117         * `Capabilities::getDetails()`. Call `AMessage::getInt32()` with the
118         * same key to retrieve the value.
119         *
120         * @param key The key.
121         * @param value The `int32_t` value.
122         */
123        void addDetail(const char* key, int32_t value);
124        /**
125         * Add a profile-level pair. If this profile-level pair already exists,
126         * it will be ignored.
127         *
128         * @param profile The "profile" component.
129         * @param level The "level" component.
130         */
131        void addProfileLevel(uint32_t profile, uint32_t level);
132        /**
133         * Add a color format. If this color format already exists, it will be
134         * ignored.
135         *
136         * @param format The color format.
137         */
138        void addColorFormat(uint32_t format);
139        /**
140         * Add flags. The underlying operation is bitwise-or. In other words,
141         * bits that have already been set will be ignored.
142         *
143         * @param flags The additional flags.
144         */
145        void addFlags(uint32_t flags);
146    private:
147        /**
148         * The associated `Capabilities` object.
149         */
150        Capabilities* mCap;
151        /**
152         * Construct a writer for the given `Capabilities` object.
153         *
154         * @param cap The `Capabilities` object to be written to.
155         */
156        CapabilitiesWriter(Capabilities* cap);
157
158        friend MediaCodecInfoWriter;
159    };
160
161    bool isEncoder() const;
162    void getSupportedMimes(Vector<AString> *mimes) const;
163    const sp<Capabilities> getCapabilitiesFor(const char *mime) const;
164    const char *getCodecName() const;
165
166    /**
167     * Return the name of the service that hosts the codec. This value is not
168     * visible at the Java level.
169     *
170     * Currently, this is the "instance name" of the IOmx service.
171     */
172    const char *getOwnerName() const;
173    uint32_t rank() const;
174
175    /**
176     * Serialization over Binder
177     */
178    static sp<MediaCodecInfo> FromParcel(const Parcel &parcel);
179    status_t writeToParcel(Parcel *parcel) const;
180
181private:
182    AString mName;
183    AString mOwner;
184    bool mIsEncoder;
185    KeyedVector<AString, sp<Capabilities> > mCaps;
186    uint32_t mRank;
187
188    ssize_t getCapabilityIndex(const char *mime) const;
189
190    /**
191     * Construct an `MediaCodecInfo` object. After the construction, its
192     * information can be set via an `MediaCodecInfoWriter` object obtained from
193     * `MediaCodecListWriter::addMediaCodecInfo()`.
194     */
195    MediaCodecInfo();
196
197    DISALLOW_COPY_AND_ASSIGN(MediaCodecInfo);
198
199    friend class MediaCodecListOverridesTest;
200    friend struct MediaCodecInfoWriter;
201    friend struct MediaCodecListWriter;
202};
203
204/**
205 * This class is to be used by a `MediaCodecListBuilderBase` instance to
206 * populate information inside the associated `MediaCodecInfo` object.
207 *
208 * The only place where an instance of `MediaCodecInfoWriter` can be constructed
209 * is `MediaCodecListWriter::addMediaCodecInfo()`. A `MediaCodecListBuilderBase`
210 * instance should call `MediaCodecListWriter::addMediaCodecInfo()` on the given
211 * `MediaCodecListWriter` object given as an input to
212 * `MediaCodecListBuilderBase::buildMediaCodecList()`.
213 */
214struct MediaCodecInfoWriter {
215    /**
216     * Set the name of the codec.
217     *
218     * @param name The new name.
219     */
220    void setName(const char* name);
221    /**
222     * Set the owner name of the codec.
223     *
224     * This "owner name" is the name of the `IOmx` instance that supports this
225     * codec.
226     *
227     * @param owner The new owner name.
228     */
229    void setOwner(const char* owner);
230    /**
231     * Set whether this codec is an encoder or a decoder.
232     *
233     * @param isEncoder Whether this codec is an encoder or a decoder.
234     */
235    void setEncoder(bool isEncoder = true);
236    /**
237     * Add a mime to an indexed list and return a `CapabilitiesWriter` object
238     * that can be used for modifying the associated `Capabilities`.
239     *
240     * If the mime already exists, this function will return the
241     * `CapabilitiesWriter` associated with the mime.
242     *
243     * @param[in] mime The name of a new mime to add.
244     * @return writer The `CapabilitiesWriter` object for modifying the
245     * `Capabilities` associated with the mime. `writer` will be valid
246     * regardless of whether `mime` already exists or not.
247     */
248    std::unique_ptr<MediaCodecInfo::CapabilitiesWriter> addMime(
249            const char* mime);
250    /**
251     * Remove a mime.
252     *
253     * @param mime The name of the mime to remove.
254     * @return `true` if `mime` is removed; `false` if `mime` is not found.
255     */
256    bool removeMime(const char* mime);
257    /**
258     * Set rank of the codec. MediaCodecList will stable-sort the list according
259     * to rank in non-descending order.
260     *
261     * @param rank The rank of the component.
262     */
263    void setRank(uint32_t rank);
264private:
265    /**
266     * The associated `MediaCodecInfo`.
267     */
268    MediaCodecInfo* mInfo;
269    /**
270     * Construct the `MediaCodecInfoWriter` object associated with the given
271     * `MediaCodecInfo` object.
272     *
273     * @param info The underlying `MediaCodecInfo` object.
274     */
275    MediaCodecInfoWriter(MediaCodecInfo* info);
276
277    DISALLOW_COPY_AND_ASSIGN(MediaCodecInfoWriter);
278
279    friend struct MediaCodecListWriter;
280};
281
282}  // namespace android
283
284#endif  // MEDIA_CODEC_INFO_H_
285
286
287