160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber/*
260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Copyright (C) 2012 The Android Open Source Project
360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber *
460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License");
560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * you may not use this file except in compliance with the License.
660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * You may obtain a copy of the License at
760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber *
860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber *      http://www.apache.org/licenses/LICENSE-2.0
960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber *
1060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Unless required by applicable law or agreed to in writing, software
1160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS,
1260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * See the License for the specific language governing permissions and
1460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * limitations under the License.
1560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */
1660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
1760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberpackage android.media;
1860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
1975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wuimport android.annotation.NonNull;
2075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wuimport android.annotation.Nullable;
21b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Log;
22b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Pair;
23b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Range;
24b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Rational;
25b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Size;
26b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
27b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.ArrayList;
28b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Arrays;
29b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.HashMap;
30b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Map;
31b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Set;
32b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
33b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static android.media.Utils.intersectSortedDistinctRanges;
34b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static android.media.Utils.sortDistinctRanges;
35b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
36c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main/**
37c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Provides information about a given media codec available on the device. You can
38c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * iterate through all codecs available by querying {@link MediaCodecList}. For example,
39c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * here's how to find an encoder that supports a given MIME type:
40c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <pre>
41c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * private static MediaCodecInfo selectCodec(String mimeType) {
42c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *     int numCodecs = MediaCodecList.getCodecCount();
43c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *     for (int i = 0; i &lt; numCodecs; i++) {
44c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *         MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i);
45c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *
46c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *         if (!codecInfo.isEncoder()) {
47c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *             continue;
48c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *         }
49c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *
50c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *         String[] types = codecInfo.getSupportedTypes();
51c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *         for (int j = 0; j &lt; types.length; j++) {
52c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *             if (types[j].equalsIgnoreCase(mimeType)) {
53c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *                 return codecInfo;
54c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *             }
55c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *         }
56c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *     }
57c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *     return null;
58c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * }</pre>
59c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main *
60c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main */
6160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberpublic final class MediaCodecInfo {
62b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    private boolean mIsEncoder;
63b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    private String mName;
64b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    private Map<String, CodecCapabilities> mCaps;
6560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
66b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    /* package private */ MediaCodecInfo(
67b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            String name, boolean isEncoder, CodecCapabilities[] caps) {
68b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        mName = name;
69b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        mIsEncoder = isEncoder;
70b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        mCaps = new HashMap<String, CodecCapabilities>();
71b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        for (CodecCapabilities c: caps) {
72217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mCaps.put(c.getMimeType(), c);
73b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
7460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
7560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
7660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    /**
7760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * Retrieve the codec name.
7860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     */
7960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    public final String getName() {
80b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        return mName;
8160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
8260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
8360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    /**
8460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * Query if the codec is an encoder.
8560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     */
8660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    public final boolean isEncoder() {
87b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        return mIsEncoder;
8860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
8960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
9060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    /**
9160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     * Query the media types supported by the codec.
9260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber     */
9360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    public final String[] getSupportedTypes() {
94b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        Set<String> typeSet = mCaps.keySet();
95b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        String[] types = typeSet.toArray(new String[typeSet.size()]);
96b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        Arrays.sort(types);
97b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        return types;
9860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
9960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static int checkPowerOfTwo(int value, String message) {
101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        if ((value & (value - 1)) != 0) {
102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            throw new IllegalArgumentException(message);
103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        return value;
105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    }
106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static class Feature {
108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public String mName;
109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public int mValue;
110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean mDefault;
111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Feature(String name, int value, boolean def) {
112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mName = name;
113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mValue = value;
114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mDefault = def;
115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    }
117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
118217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    // COMMON CONSTANTS
119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final Range<Integer> POSITIVE_INTEGERS =
120217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        Range.create(1, Integer.MAX_VALUE);
121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final Range<Long> POSITIVE_LONGS =
122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        Range.create(1l, Long.MAX_VALUE);
123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final Range<Rational> POSITIVE_RATIONALS =
124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        Range.create(new Rational(1, Integer.MAX_VALUE),
125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                     new Rational(Integer.MAX_VALUE, 1));
126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768);
127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
128216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang    private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000);
129ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu    private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
130ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu    private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256;
131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    // found stuff that is not supported by framework (=> this should not happen)
133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final int ERROR_UNRECOGNIZED   = (1 << 0);
134217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    // found profile/level for which we don't have capability estimates
135217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final int ERROR_UNSUPPORTED    = (1 << 1);
136217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    // have not found any profile/level for which we don't have capability estimate
137217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    private static final int ERROR_NONE_SUPPORTED = (1 << 2);
138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
139217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
140ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber    /**
141c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * Encapsulates the capabilities of a given codec component.
142c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * For example, what profile/level combinations it supports and what colorspaces
14380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar     * it is capable of providing the decoded data in, as well as some
14480c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar     * codec-type specific capability flags.
145c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * <p>You can get an instance for a given {@link MediaCodecInfo} object with
146c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * {@link MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType()}, passing a MIME type.
147ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber     */
14860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    public static final class CodecCapabilities {
149b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public CodecCapabilities() {
150b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
151b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
152b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        // CLASSIFICATION
153b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private String mMime;
154ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu        private int mMaxSupportedInstances;
155b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
156b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        // LEGACY FIELDS
157b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
158ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber        // Enumerates supported profile/level combinations as defined
159ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber        // by the type of encoded data. These combinations impose restrictions
160ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber        // on video resolution, bitrate... and limit the available encoder tools
161ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber        // such as B-frame support, arithmetic coding...
162b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public CodecProfileLevel[] profileLevels;  // NOTE this array is modifiable by user
16360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
16460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_COLOR_FORMATTYPE
165e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
166b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatMonochrome              = 1;
167e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
168b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format8bitRGB332              = 2;
169e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
170b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format12bitRGB444             = 3;
171e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
172b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format16bitARGB4444           = 4;
173e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
174b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format16bitARGB1555           = 5;
175b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
176b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
177b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * 16 bits per pixel RGB color format, with 5-bit red & blue and 6-bit green component.
178b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
179e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Using 16-bit little-endian representation, colors stored as Red 15:11, Green 10:5, Blue 4:0.
180b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <pre>
181b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *            byte                   byte
182b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  <--------- i --------> | <------ i + 1 ------>
183b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
184b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * |     BLUE     |      GREEN      |     RED      |
185b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
186b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  0           4  5     7   0     2  3           7
187b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * bit
188b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * </pre>
189e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *
190e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This format corresponds to {@link android.graphics.PixelFormat#RGB_565} and
191e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link android.graphics.ImageFormat#RGB_565}.
192b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
193b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format16bitRGB565             = 6;
194b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_Format16bitRGB565}. */
195b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format16bitBGR565             = 7;
196e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
197b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format18bitRGB666             = 8;
198e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
199b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format18bitARGB1665           = 9;
200e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
201b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format19bitARGB1666           = 10;
202b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
203e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format24bitBGR888} or {@link #COLOR_FormatRGBFlexible}. */
204e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        public static final int COLOR_Format24bitRGB888             = 11;
205e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar
206b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
207b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * 24 bits per pixel RGB color format, with 8-bit red, green & blue components.
208b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
209e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Using 24-bit little-endian representation, colors stored as Red 7:0, Green 15:8, Blue 23:16.
210b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <pre>
211b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *         byte              byte             byte
212b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----->
213b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +-----------------+-----------------+-----------------+
214e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * |       RED       |      GREEN      |       BLUE      |
215b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +-----------------+-----------------+-----------------+
216b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * </pre>
217e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *
218e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This format corresponds to {@link android.graphics.PixelFormat#RGB_888}, and can also be
219e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * represented as a flexible format by {@link #COLOR_FormatRGBFlexible}.
220b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
221b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format24bitBGR888             = 12;
222e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
223b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format24bitARGB1887           = 13;
224e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
225b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format25bitARGB1888           = 14;
226b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
227b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
228e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * @deprecated Use {@link #COLOR_Format32bitABGR8888} Or {@link #COLOR_FormatRGBAFlexible}.
229b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
230b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format32bitBGRA8888           = 15;
231b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
232e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * @deprecated Use {@link #COLOR_Format32bitABGR8888} Or {@link #COLOR_FormatRGBAFlexible}.
233b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
234b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format32bitARGB8888           = 16;
235b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
236b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV411Planar            = 17;
237b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
238b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV411PackedPlanar      = 18;
239b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
240b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV420Planar            = 19;
241b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
242b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV420PackedPlanar      = 20;
243b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
244b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV420SemiPlanar        = 21;
245b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
246b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
247b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV422Planar            = 22;
248b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
249b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV422PackedPlanar      = 23;
250b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
251b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV422SemiPlanar        = 24;
252b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
253b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
254b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYCbYCr                  = 25;
255b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
256b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYCrYCb                  = 26;
257b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
258b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatCbYCrY                  = 27;
259b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
260b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatCrYCbY                  = 28;
261b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
262e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV444Flexible}. */
263b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV444Interleaved       = 29;
264b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
265e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
266e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * SMIA 8-bit Bayer format.
267e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Each byte represents the top 8-bits of a 10-bit signal.
268e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
269b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatRawBayer8bit            = 30;
270e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
271e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * SMIA 10-bit Bayer format.
272e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
273b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatRawBayer10bit           = 31;
274e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar
275e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
276e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * SMIA 8-bit compressed Bayer format.
277e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Each byte represents a sample from the 10-bit signal that is compressed into 8-bits
278e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * using DPCM/PCM compression, as defined by the SMIA Functional Specification.
279e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
280b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatRawBayer8bitcompressed  = 32;
281b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
282b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatL8}. */
283b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatL2                      = 33;
284b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatL8}. */
285b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatL4                      = 34;
286b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
287b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
288b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * 8 bits per pixel Y color format.
289b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
290b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * Each byte contains a single pixel.
291e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This format corresponds to {@link android.graphics.PixelFormat#L_8}.
292b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
293b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatL8                      = 35;
294b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
295b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
296b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * 16 bits per pixel, little-endian Y color format.
297b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
298b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <pre>
299b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *            byte                   byte
300b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  <--------- i --------> | <------ i + 1 ------>
301b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
302b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * |                       Y                       |
303b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
304b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  0                    7   0                    7
305b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * bit
306b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * </pre>
307b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
308b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatL16                     = 36;
309e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_FormatL16}. */
310b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatL24                     = 37;
311b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
312b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
313b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * 32 bits per pixel, little-endian Y color format.
314b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
315b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <pre>
316b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *         byte              byte             byte              byte
317b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 ----->
318b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +-----------------+-----------------+-----------------+-----------------+
319b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * |                                   Y                                   |
320b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * +-----------------+-----------------+-----------------+-----------------+
321b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *  0               7 0               7 0               7 0               7
322b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * bit
323b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * </pre>
324e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *
325e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * @deprecated Use {@link #COLOR_FormatL16}.
326b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
327b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatL32                     = 38;
328b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
329b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
330b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV420PackedSemiPlanar  = 39;
331b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */
332b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV422PackedSemiPlanar  = 40;
333b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
334e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */
335b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format18BitBGR666             = 41;
336b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
337e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
338b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format24BitARGB6666           = 42;
339e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */
340b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_Format24BitABGR6666           = 43;
341b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
342b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
343b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100;
34434f17dd1f615c6285f4f344eb700923e2432e48eAndy McFadden        // COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference.
34534f17dd1f615c6285f4f344eb700923e2432e48eAndy McFadden        // In OMX this is called OMX_COLOR_FormatAndroidOpaque.
346b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatSurface                   = 0x7F000789;
347b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
348e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
349e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * 32 bits per pixel RGBA color format, with 8-bit red, green, blue, and alpha components.
350e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * <p>
351e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Using 32-bit little-endian representation, colors stored as Red 7:0, Green 15:8,
352e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Blue 23:16, and Alpha 31:24.
353e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * <pre>
354e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *         byte              byte             byte              byte
355e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *  <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 ----->
356e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * +-----------------+-----------------+-----------------+-----------------+
357e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * |       RED       |      GREEN      |       BLUE      |      ALPHA      |
358e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * +-----------------+-----------------+-----------------+-----------------+
359e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * </pre>
360e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *
361e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This corresponds to {@link android.graphics.PixelFormat#RGBA_8888}.
362e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
363e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        public static final int COLOR_Format32bitABGR8888             = 0x7F00A000;
364b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
365b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
366b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * Flexible 12 bits per pixel, subsampled YUV color format with 8-bit chroma and luma
367b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * components.
368b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
369b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * Chroma planes are subsampled by 2 both horizontally and vertically.
370b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * Use this format with {@link Image}.
371e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This format corresponds to {@link android.graphics.ImageFormat#YUV_420_888},
372e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * and can represent the {@link #COLOR_FormatYUV411Planar},
373e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_FormatYUV411PackedPlanar}, {@link #COLOR_FormatYUV420Planar},
374e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_FormatYUV420PackedPlanar}, {@link #COLOR_FormatYUV420SemiPlanar}
375e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * and {@link #COLOR_FormatYUV420PackedSemiPlanar} formats.
376b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *
377b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * @see Image#getFormat
378b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
379b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_FormatYUV420Flexible            = 0x7F420888;
380b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
381b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /**
382b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * Flexible 16 bits per pixel, subsampled YUV color format with 8-bit chroma and luma
383b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * components.
384b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * <p>
385e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Chroma planes are horizontally subsampled by 2. Use this format with {@link Image}.
386e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This format corresponds to {@link android.graphics.ImageFormat#YUV_422_888},
387e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * and can represent the {@link #COLOR_FormatYCbYCr}, {@link #COLOR_FormatYCrYCb},
388e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_FormatCbYCrY}, {@link #COLOR_FormatCrYCbY},
389e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_FormatYUV422Planar}, {@link #COLOR_FormatYUV422PackedPlanar},
390e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_FormatYUV422SemiPlanar} and {@link #COLOR_FormatYUV422PackedSemiPlanar}
391e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * formats.
392b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         *
393b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         * @see Image#getFormat
394b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar         */
395b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        public static final int COLOR_FormatYUV422Flexible            = 0x7F422888;
396b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar
397e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
398e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Flexible 24 bits per pixel YUV color format with 8-bit chroma and luma
399e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * components.
400e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * <p>
401e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Chroma planes are not subsampled. Use this format with {@link Image}.
402e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * This format corresponds to {@link android.graphics.ImageFormat#YUV_444_888},
403e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * and can represent the {@link #COLOR_FormatYUV444Interleaved} format.
404e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * @see Image#getFormat
405e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
406e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        public static final int COLOR_FormatYUV444Flexible            = 0x7F444888;
407e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar
408e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
409e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Flexible 24 bits per pixel RGB color format with 8-bit red, green and blue
410e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * components.
411e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * <p>
412e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Use this format with {@link Image}. This format corresponds to
413e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link android.graphics.ImageFormat#FLEX_RGB_888}, and can represent
414e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_Format24bitBGR888} and {@link #COLOR_Format24bitRGB888} formats.
415e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * @see Image#getFormat.
416e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
417e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        public static final int COLOR_FormatRGBFlexible               = 0x7F36B888;
418e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar
419e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        /**
420e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Flexible 32 bits per pixel RGBA color format with 8-bit red, green, blue, and alpha
421e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * components.
422e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * <p>
423e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * Use this format with {@link Image}. This format corresponds to
424e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link android.graphics.ImageFormat#FLEX_RGBA_8888}, and can represent
425e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_Format32bitBGRA8888}, {@link #COLOR_Format32bitABGR8888} and
426e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * {@link #COLOR_Format32bitARGB8888} formats.
427e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         *
428e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         * @see Image#getFormat
429e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar         */
430e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar        public static final int COLOR_FormatRGBAFlexible              = 0x7F36A888;
431e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar
432b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar        /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */
433b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int COLOR_QCOM_FormatYUV420SemiPlanar     = 0x7fa30c00;
43460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
43560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        /**
43660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         * Defined in the OpenMAX IL specs, color format values are drawn from
43760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         * OMX_COLOR_FORMATTYPE.
43860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         */
439b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public int[] colorFormats; // NOTE this array is modifiable by user
44080c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar
441b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        // FEATURES
442b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
443b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private int mFlagsSupported;
444b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private int mFlagsRequired;
445b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private int mFlagsVerified;
44680c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar
44780c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar        /**
44880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar         * <b>video decoder only</b>: codec supports seamless resolution changes.
44980c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar         */
450b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final String FEATURE_AdaptivePlayback       = "adaptive-playback";
451b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
452b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
453b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * <b>video decoder only</b>: codec supports secure decryption.
454b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
455b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final String FEATURE_SecurePlayback         = "secure-playback";
456b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
457b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
458b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * <b>video or audio decoder only</b>: codec supports tunneled playback.
459b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
460b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final String FEATURE_TunneledPlayback       = "tunneled-playback";
46180c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar
46280c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar        /**
463d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang         * <b>video decoder only</b>: codec supports queuing partial frames.
464d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang         */
465d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang        public static final String FEATURE_PartialFrame = "partial-frame";
466d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang
467d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang        /**
468e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang         * <b>video encoder only</b>: codec supports intra refresh.
469e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang         */
470e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang        public static final String FEATURE_IntraRefresh = "intra-refresh";
471e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang
472e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang        /**
47380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar         * Query codec feature capabilities.
474b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * <p>
475b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * These features are supported to be used by the codec.  These
476b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * include optional features that can be turned on, as well as
477b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * features that are always on.
47880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar         */
47980c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar        public final boolean isFeatureSupported(String name) {
480b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return checkFeature(name, mFlagsSupported);
481b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
482b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
483b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
484b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * Query codec feature requirements.
485b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * <p>
486b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * These features are required to be used by the codec, and as such,
487b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * they are always turned on.
488b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
489b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public final boolean isFeatureRequired(String name) {
490b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return checkFeature(name, mFlagsRequired);
491b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
492b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
493b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private static final Feature[] decoderFeatures = {
494b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            new Feature(FEATURE_AdaptivePlayback, (1 << 0), true),
495b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            new Feature(FEATURE_SecurePlayback,   (1 << 1), false),
496b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            new Feature(FEATURE_TunneledPlayback, (1 << 2), false),
497d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang            new Feature(FEATURE_PartialFrame,     (1 << 3), false),
498b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        };
499b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
500e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang        private static final Feature[] encoderFeatures = {
501e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang            new Feature(FEATURE_IntraRefresh, (1 << 0), false),
502e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang        };
503e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang
504b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /** @hide */
505b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public String[] validFeatures() {
506b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            Feature[] features = getValidFeatures();
507b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            String[] res = new String[features.length];
508b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            for (int i = 0; i < res.length; i++) {
509b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                res[i] = features[i].mName;
510b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
511b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return res;
512b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
513b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
514b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private Feature[] getValidFeatures() {
515b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (!isEncoder()) {
516b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                return decoderFeatures;
517b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
518e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang            return encoderFeatures;
519b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
520b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
521b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private boolean checkFeature(String name, int flags) {
522b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            for (Feature feat: getValidFeatures()) {
523b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                if (feat.mName.equals(name)) {
524b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    return (flags & feat.mValue) != 0;
525b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
52680c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar            }
52780c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar            return false;
52880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar        }
529b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
530b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /** @hide */
531b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public boolean isRegular() {
532b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            // regular codecs only require default features
533b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            for (Feature feat: getValidFeatures()) {
534b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                if (!feat.mDefault && isFeatureRequired(feat.mName)) {
535b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    return false;
536b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
537b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
538b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return true;
539b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
540b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
541b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
542b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * Query whether codec supports a given {@link MediaFormat}.
543afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         *
544afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * <p class=note>
545afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP},
546afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE
547afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * frame rate}. Use
548afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code>
549afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * to clear any existing frame rate setting in the format.
550db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         * <p>
551db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *
552db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         * The following table summarizes the format keys considered by this method.
553db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *
554db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         * <table style="width: 0%">
555db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *  <thead>
556db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   <tr>
557db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <th rowspan=3>OS Version(s)</th>
558db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td colspan=3>{@code MediaFormat} keys considered for</th>
559db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr><tr>
560db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <th>Audio Codecs</th>
561db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <th>Video Codecs</th>
562db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <th>Encoders</th>
563db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr>
564db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *  </thead>
565db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *  <tbody>
566db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   <tr>
567db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</th>
568db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td rowspan=3>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
569db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_SAMPLE_RATE},<br>
570db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_CHANNEL_COUNT},</td>
571db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br>
572db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link CodecCapabilities#FEATURE_AdaptivePlayback}<sup>D</sup>,<br>
573db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link CodecCapabilities#FEATURE_SecurePlayback}<sup>D</sup>,<br>
574db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link CodecCapabilities#FEATURE_TunneledPlayback}<sup>D</sup>,<br>
575db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_WIDTH},<br>
576db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_HEIGHT},<br>
577db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        <strong>no</strong> {@code KEY_FRAME_RATE}</td>
578db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td rowspan=4>{@link MediaFormat#KEY_BITRATE_MODE},<br>
579db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_PROFILE}
580db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        (and/or {@link MediaFormat#KEY_AAC_PROFILE}<sup>~</sup>),<br>
581db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        <!-- {link MediaFormat#KEY_QUALITY},<br> -->
582db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_COMPLEXITY}
583db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        (and/or {@link MediaFormat#KEY_FLAC_COMPRESSION_LEVEL}<sup>~</sup>)</td>
584db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr><tr>
585db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</th>
586db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td rowspan=2>as above, plus<br>
587db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_FRAME_RATE}</td>
588db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr><tr>
589db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>{@link android.os.Build.VERSION_CODES#M}</th>
590db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr><tr>
591db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>{@link android.os.Build.VERSION_CODES#N}</th>
592db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>as above, plus<br>
593db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_PROFILE},<br>
594db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
595db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_BIT_RATE}</td>
596db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td>as above, plus<br>
597db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_PROFILE},<br>
598db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_LEVEL}<sup>+</sup>,<br>
599db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> -->
600db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link MediaFormat#KEY_BIT_RATE},<br>
601db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *        {@link CodecCapabilities#FEATURE_IntraRefresh}<sup>E</sup></td>
602db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr>
603db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   <tr>
604db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    <td colspan=4>
605db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *     <p class=note><strong>Notes:</strong><br>
606db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *      *: must be specified; otherwise, method returns {@code false}.<br>
607db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *      +: method does not verify that the format parameters are supported
608db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *      by the specified level.<br>
609db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *      D: decoders only<br>
610db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *      E: encoders only<br>
611db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *      ~: if both keys are provided values must match
612db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *    </td>
613db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *   </tr>
614db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         *  </tbody>
615db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar         * </table>
616afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         *
617b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * @param format media format with optional feature directives.
618b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * @throws IllegalArgumentException if format is not a valid media format.
619b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * @return whether the codec capabilities support the given format
620b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         *         and feature requests.
621b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
622b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public final boolean isFormatSupported(MediaFormat format) {
623b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            final Map<String, Object> map = format.getMap();
624b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            final String mime = (String)map.get(MediaFormat.KEY_MIME);
625b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
626b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            // mime must match if present
627b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (mime != null && !mMime.equalsIgnoreCase(mime)) {
628b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                return false;
629b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
630b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
631b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            // check feature support
632b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            for (Feature feat: getValidFeatures()) {
633b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                Integer yesNo = (Integer)map.get(MediaFormat.KEY_FEATURE_ + feat.mName);
634dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                if (yesNo == null) {
635dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                    continue;
636dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                }
637b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                if ((yesNo == 1 && !isFeatureSupported(feat.mName)) ||
638b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                        (yesNo == 0 && isFeatureRequired(feat.mName))) {
639b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    return false;
640b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
641b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
6420581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
6430581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
6440581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            Integer level = (Integer)map.get(MediaFormat.KEY_LEVEL);
6450581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
6460581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            if (profile != null) {
6470581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                if (!supportsProfileLevel(profile, level)) {
6480581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    return false;
6490581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
6500581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
6510581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // If we recognize this profile, check that this format is supported by the
6520581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // highest level supported by the codec for that profile. (Ignore specified
6530581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // level beyond the above profile/level check as level is only used as a
6540581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
6550581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
6560581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // 1080p format is not supported even if codec supports Main Profile Level High,
6570581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // as Simple Profile does not support 1080p.
6580581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                CodecCapabilities levelCaps = null;
6590581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                int maxLevel = 0;
6600581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                for (CodecProfileLevel pl : profileLevels) {
6610581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    if (pl.profile == profile && pl.level > maxLevel) {
6620581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                        maxLevel = pl.level;
6630581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    }
6640581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
6650581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
66687436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar                // remove profile from this format otherwise levelCaps.isFormatSupported will
66787436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar                // get into this same conditon and loop forever.
66887436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar                Map<String, Object> mapWithoutProfile = new HashMap<>(map);
66987436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar                mapWithoutProfile.remove(MediaFormat.KEY_PROFILE);
67087436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar                MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile);
67187436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar                if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) {
6720581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    return false;
6730581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
6740581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
675b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
676b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                return false;
677b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
678b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (mVideoCaps != null && !mVideoCaps.supportsFormat(format)) {
679b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                return false;
680b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
681b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (mEncoderCaps != null && !mEncoderCaps.supportsFormat(format)) {
682b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                return false;
683b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
684b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return true;
685b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
686b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
6870581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar        private static boolean supportsBitrate(
6880581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                Range<Integer> bitrateRange, MediaFormat format) {
6890581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            Map<String, Object> map = format.getMap();
6900581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
6910581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            // consider max bitrate over average bitrate for support
6920581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            Integer maxBitrate = (Integer)map.get(MediaFormat.KEY_MAX_BIT_RATE);
6930581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            Integer bitrate = (Integer)map.get(MediaFormat.KEY_BIT_RATE);
6940581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            if (bitrate == null) {
6950581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                bitrate = maxBitrate;
6960581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            } else if (maxBitrate != null) {
6970581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                bitrate = Math.max(bitrate, maxBitrate);
6980581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
6990581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
7000581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            if (bitrate != null && bitrate > 0) {
7010581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                return bitrateRange.contains(bitrate);
7020581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
7030581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
7040581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            return true;
7050581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar        }
7060581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
7070581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar        private boolean supportsProfileLevel(int profile, Integer level) {
7080581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            for (CodecProfileLevel pl: profileLevels) {
7090581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                if (pl.profile != profile) {
7100581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    continue;
7110581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
7120581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
7130581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // AAC does not use levels
7140581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                if (level == null || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
7150581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    return true;
7160581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
7170581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
7180581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // H.263 levels are not completely ordered:
7190581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                // Level45 support only implies Level10 support
7200581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
7210581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    if (pl.level != level && pl.level == CodecProfileLevel.H263Level45
7220581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                            && level > CodecProfileLevel.H263Level10) {
7230581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                        continue;
7240581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    }
7250581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
7262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
7272fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                // MPEG4 levels are not completely ordered:
7282fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                // Level1 support only implies Level0 (and not Level0b) support
7292fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
7302fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    if (pl.level != level && pl.level == CodecProfileLevel.MPEG4Level1
7312fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            && level > CodecProfileLevel.MPEG4Level0) {
7322fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        continue;
7332fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    }
7342fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                }
7352fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
7362fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                // HEVC levels incorporate both tiers and levels. Verify tier support.
7372fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
7382fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    boolean supportsHighTier =
7392fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        (pl.level & CodecProfileLevel.HEVCHighTierLevels) != 0;
7402fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    boolean checkingHighTier = (level & CodecProfileLevel.HEVCHighTierLevels) != 0;
7412fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    // high tier levels are only supported by other high tier levels
7422fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    if (checkingHighTier && !supportsHighTier) {
7432fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        continue;
7442fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    }
7452fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                }
7462fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
7470581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                if (pl.level >= level) {
7480581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    // if we recognize the listed profile/level, we must also recognize the
7490581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    // profile/level arguments.
7500581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    if (createFromProfileLevel(mMime, profile, pl.level) != null) {
7510581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                        return createFromProfileLevel(mMime, profile, level) != null;
7520581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    }
7530581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                    return true;
7540581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                }
7550581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
7560581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            return false;
7570581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar        }
7580581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        // errors while reading profile levels - accessed from sister capabilities
760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        int mError;
761b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
762b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private static final String TAG = "CodecCapabilities";
763b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
764b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        // NEW-STYLE CAPABILITIES
765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private AudioCapabilities mAudioCaps;
766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private VideoCapabilities mVideoCaps;
767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private EncoderCapabilities mEncoderCaps;
768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private MediaFormat mDefaultFormat;
769b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
770b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
771b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * Returns a MediaFormat object with default values for configurations that have
772b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * defaults.
773b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public MediaFormat getDefaultFormat() {
775b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return mDefaultFormat;
776b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
777b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
778b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
779b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * Returns the mime type for which this codec-capability object was created.
780b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public String getMimeType() {
782b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return mMime;
783b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
784b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
785ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu        /**
786ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         * Returns the max number of the supported concurrent codec instances.
787ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         * <p>
788ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         * This is a hint for an upper bound. Applications should not expect to successfully
789ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         * operate more instances than the returned value, but the actual number of
790ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         * concurrently operable instances may be less as it depends on the available
791ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         * resources at time of use.
792ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu         */
793ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu        public int getMaxSupportedInstances() {
794ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu            return mMaxSupportedInstances;
795ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu        }
796ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu
797217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private boolean isAudio() {
798217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mAudioCaps != null;
799217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
800217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
801b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the audio capabilities or {@code null} if this is not an audio codec.
803b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public AudioCapabilities getAudioCapabilities() {
805217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mAudioCaps;
806b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
807b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
808b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private boolean isEncoder() {
809b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return mEncoderCaps != null;
810b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
811b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
812b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the encoding capabilities or {@code null} if this is not an encoder.
814b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public EncoderCapabilities getEncoderCapabilities() {
816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mEncoderCaps;
817b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
818b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
819b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private boolean isVideo() {
820b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return mVideoCaps != null;
821b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
822b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
823b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
824b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * Returns the video capabilities or {@code null} if this is not a video codec.
825b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public VideoCapabilities getVideoCapabilities() {
827b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return mVideoCaps;
828b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
829b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public CodecCapabilities dup() {
832a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            CodecCapabilities caps = new CodecCapabilities();
833a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang
834a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            // profileLevels and colorFormats may be modified by client.
835a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.profileLevels = Arrays.copyOf(profileLevels, profileLevels.length);
836a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.colorFormats = Arrays.copyOf(colorFormats, colorFormats.length);
837a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang
838a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mMime = mMime;
839a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mMaxSupportedInstances = mMaxSupportedInstances;
840a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mFlagsRequired = mFlagsRequired;
841a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mFlagsSupported = mFlagsSupported;
842a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mFlagsVerified = mFlagsVerified;
843a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mAudioCaps = mAudioCaps;
844a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mVideoCaps = mVideoCaps;
845a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mEncoderCaps = mEncoderCaps;
846a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mDefaultFormat = mDefaultFormat;
847a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            caps.mCapabilitiesInfo = mCapabilitiesInfo;
848a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang
849a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang            return caps;
850217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
851217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
852b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
853b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * Retrieve the codec capabilities for a certain {@code mime type}, {@code
854b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * profile} and {@code level}.  If the type, or profile-level combination
855b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         * is not understood by the framework, it returns null.
8560d8337c3143867f51a52814830b0dd48535338b7Lajos Molnar         * <p class=note> In {@link android.os.Build.VERSION_CODES#M}, calling this
8570d8337c3143867f51a52814830b0dd48535338b7Lajos Molnar         * method without calling any method of the {@link MediaCodecList} class beforehand
8580d8337c3143867f51a52814830b0dd48535338b7Lajos Molnar         * results in a {@link NullPointerException}.</p>
859b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
860a18b69f5907ef27b9954dfcbe8f60d29fcec2be7Lajos Molnar        public static CodecCapabilities createFromProfileLevel(
861b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                String mime, int profile, int level) {
862b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            CodecProfileLevel pl = new CodecProfileLevel();
863b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            pl.profile = profile;
864b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            pl.level = level;
865b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            MediaFormat defaultFormat = new MediaFormat();
866b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            defaultFormat.setString(MediaFormat.KEY_MIME, mime);
867b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
868b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            CodecCapabilities ret = new CodecCapabilities(
869b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                new CodecProfileLevel[] { pl }, new int[0], true /* encoder */,
870b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                0 /* flags */, defaultFormat, new MediaFormat() /* info */);
871b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (ret.mError != 0) {
872b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                return null;
873b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
874b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return ret;
875b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
876b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
877b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /* package private */ CodecCapabilities(
878b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                CodecProfileLevel[] profLevs, int[] colFmts,
879b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                boolean encoder, int flags,
880b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                Map<String, Object>defaultFormatMap,
881b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                Map<String, Object>capabilitiesMap) {
882b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            this(profLevs, colFmts, encoder, flags,
883b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    new MediaFormat(defaultFormatMap),
884b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    new MediaFormat(capabilitiesMap));
885b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
886b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
887b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        private MediaFormat mCapabilitiesInfo;
888b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
889b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /* package private */ CodecCapabilities(
890b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                CodecProfileLevel[] profLevs, int[] colFmts, boolean encoder, int flags,
891b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                MediaFormat defaultFormat, MediaFormat info) {
892b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            final Map<String, Object> map = info.getMap();
893b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            colorFormats = colFmts;
894b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            mFlagsVerified = flags;
895b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            mDefaultFormat = defaultFormat;
896b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            mCapabilitiesInfo = info;
897b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            mMime = mDefaultFormat.getString(MediaFormat.KEY_MIME);
898b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
8998acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            /* VP9 introduced profiles around 2016, so some VP9 codecs may not advertise any
9008acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar               supported profiles. Determine the level for them using the info they provide. */
9018acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (profLevs.length == 0 && mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
9028acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                CodecProfileLevel profLev = new CodecProfileLevel();
9038acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                profLev.profile = CodecProfileLevel.VP9Profile0;
9048acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                profLev.level = VideoCapabilities.equivalentVP9Level(info);
9058acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                profLevs = new CodecProfileLevel[] { profLev };
9068acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            }
9078acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            profileLevels = profLevs;
9088acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
909b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (mMime.toLowerCase().startsWith("audio/")) {
910b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                mAudioCaps = AudioCapabilities.create(info, this);
911a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang                mAudioCaps.getDefaultFormat(mDefaultFormat);
91293cf8b260e5b1d5fdad364f24fbdcd3864874fb6Chong Zhang            } else if (mMime.toLowerCase().startsWith("video/")
91393cf8b260e5b1d5fdad364f24fbdcd3864874fb6Chong Zhang                    || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_IMAGE_ANDROID_HEIC)) {
914b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                mVideoCaps = VideoCapabilities.create(info, this);
915b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
916b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (encoder) {
917b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                mEncoderCaps = EncoderCapabilities.create(info, this);
918a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang                mEncoderCaps.getDefaultFormat(mDefaultFormat);
919b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
920b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
921ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu            final Map<String, Object> global = MediaCodecList.getGlobalSettings();
922ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu            mMaxSupportedInstances = Utils.parseIntSafely(
92371b5a5866d8ba0eaf45972741b8f1dece36b5d03Ronghua Wu                    global.get("max-concurrent-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES);
924ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu
925ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu            int maxInstances = Utils.parseIntSafely(
92671b5a5866d8ba0eaf45972741b8f1dece36b5d03Ronghua Wu                    map.get("max-concurrent-instances"), mMaxSupportedInstances);
927ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu            mMaxSupportedInstances =
928ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu                    Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances);
929ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu
930b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            for (Feature feat: getValidFeatures()) {
931981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar                String key = MediaFormat.KEY_FEATURE_ + feat.mName;
932981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar                Integer yesNo = (Integer)map.get(key);
933b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                if (yesNo == null) {
934b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    continue;
935dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                }
936dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                if (yesNo > 0) {
937b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                    mFlagsRequired |= feat.mValue;
938b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
939dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                mFlagsSupported |= feat.mValue;
940dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar                mDefaultFormat.setInteger(key, 1);
941b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                // TODO restrict features by mFlagsVerified once all codecs reliably verify them
942b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
943b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
944217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    }
945b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
946217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    /**
947217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar     * A class that supports querying the audio capabilities of a codec.
948217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar     */
949217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    public static final class AudioCapabilities {
950217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private static final String TAG = "AudioCapabilities";
951217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private CodecCapabilities mParent;
952217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mBitrateRange;
953217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
954217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int[] mSampleRates;
955217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer>[] mSampleRateRanges;
956217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mMaxInputChannelCount;
957217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
958217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private static final int MAX_INPUT_CHANNEL_COUNT = 30;
959217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
960217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
961217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported bitrates in bits/second.
962217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
963217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getBitrateRange() {
964217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mBitrateRange;
965217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
966217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
967217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
968217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the array of supported sample rates if the codec
969217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * supports only discrete values.  Otherwise, it returns
970217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * {@code null}.  The array is sorted in ascending order.
971217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
972217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public int[] getSupportedSampleRates() {
973217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return Arrays.copyOf(mSampleRates, mSampleRates.length);
974217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
975217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
976217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
977217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the array of supported sample rate ranges.  The
978217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * array is sorted in ascending order, and the ranges are
979217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * distinct.
980217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
981217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer>[] getSupportedSampleRateRanges() {
982217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return Arrays.copyOf(mSampleRateRanges, mSampleRateRanges.length);
983217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
984217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
985217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
986217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the maximum number of input channels supported.  The codec
987217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * supports any number of channels between 1 and this maximum value.
988217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
989217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public int getMaxInputChannelCount() {
990217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mMaxInputChannelCount;
991217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
992b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
993217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /* no public constructor */
994217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private AudioCapabilities() { }
995217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
996217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
997217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public static AudioCapabilities create(
998217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                MediaFormat info, CodecCapabilities parent) {
999217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            AudioCapabilities caps = new AudioCapabilities();
1000217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            caps.init(info, parent);
1001217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return caps;
1002217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1003217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1004a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang        private void init(MediaFormat info, CodecCapabilities parent) {
1005217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mParent = parent;
1006217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            initWithPlatformLimits();
1007217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyLevelLimits();
1008217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            parseFromInfo(info);
1009217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1010217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1011217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void initWithPlatformLimits() {
1012217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBitrateRange = Range.create(0, Integer.MAX_VALUE);
1013217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mMaxInputChannelCount = MAX_INPUT_CHANNEL_COUNT;
1014217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // mBitrateRange = Range.create(1, 320000);
1015217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSampleRateRanges = new Range[] { Range.create(8000, 96000) };
1016217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSampleRates = null;
1017217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1018217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1019217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private boolean supports(Integer sampleRate, Integer inputChannels) {
1020217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // channels and sample rates are checked orthogonally
1021217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (inputChannels != null &&
1022217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    (inputChannels < 1 || inputChannels > mMaxInputChannelCount)) {
1023217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                return false;
1024b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1025217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (sampleRate != null) {
1026217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int ix = Utils.binarySearchDistinctRanges(
1027217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mSampleRateRanges, sampleRate);
1028217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (ix < 0) {
1029217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    return false;
1030217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1031217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1032217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return true;
1033217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1034b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1035217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1036217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Query whether the sample rate is supported by the codec.
1037217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1038217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean isSampleRateSupported(int sampleRate) {
1039217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return supports(sampleRate, null);
1040217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1041217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1042217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** modifies rates */
1043217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void limitSampleRates(int[] rates) {
1044217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Arrays.sort(rates);
1045217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>();
1046217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            for (int rate: rates) {
1047217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (supports(rate, null /* channels */)) {
1048217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    ranges.add(Range.create(rate, rate));
1049217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1050b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1051217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSampleRateRanges = ranges.toArray(new Range[ranges.size()]);
1052217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            createDiscreteSampleRates();
1053217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1054b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1055217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void createDiscreteSampleRates() {
1056217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSampleRates = new int[mSampleRateRanges.length];
1057217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            for (int i = 0; i < mSampleRateRanges.length; i++) {
1058217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mSampleRates[i] = mSampleRateRanges[i].getLower();
1059217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1060217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1061b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1062217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** modifies rateRanges */
1063217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void limitSampleRates(Range<Integer>[] rateRanges) {
1064217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            sortDistinctRanges(rateRanges);
1065217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges);
1066217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1067217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // check if all values are discrete
1068217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            for (Range<Integer> range: mSampleRateRanges) {
1069217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (!range.getLower().equals(range.getUpper())) {
1070217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mSampleRates = null;
1071217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    return;
1072217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1073b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1074217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            createDiscreteSampleRates();
1075217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1076217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1077217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyLevelLimits() {
1078217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int[] sampleRates = null;
1079217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Range<Integer> sampleRateRange = null, bitRates = null;
1080f31d11341e689ff5a630350cb48d30ff0ec21e70Robert Shih            int maxChannels = MAX_INPUT_CHANNEL_COUNT;
1081217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            String mime = mParent.getMimeType();
1082217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1083217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG)) {
1084217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] {
1085217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        8000, 11025, 12000,
1086217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        16000, 22050, 24000,
1087217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        32000, 44100, 48000 };
1088217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(8000, 320000);
1089217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 2;
1090217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) {
1091217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] { 8000 };
1092217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(4750, 12200);
1093217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 1;
1094217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)) {
1095217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] { 16000 };
1096217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(6600, 23850);
1097217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 1;
1098217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
1099217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] {
1100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        7350, 8000,
1101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        11025, 12000, 16000,
1102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        22050, 24000, 32000,
1103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        44100, 48000, 64000,
1104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        88200, 96000 };
1105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(8000, 510000);
1106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 48;
1107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS)) {
1108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(32000, 500000);
1109610e288de6727d9be3277777e6c5abca4b18aa86Lajos Molnar                sampleRateRange = Range.create(8000, 192000);
1110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 255;
1111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS)) {
1112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(6000, 510000);
1113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000 };
1114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 255;
1115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW)) {
1116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRateRange = Range.create(1, 96000);
1117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(1, 10000000);
1118bd2c3d65d6b62b5a359268246e7ebe96904bd851Glenn Kasten                maxChannels = AudioTrack.CHANNEL_COUNT_MAX;
1119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
1120217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRateRange = Range.create(1, 655350);
1121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // lossless codec, so bitrate is ignored
1122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 255;
1123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
1124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)) {
1125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] { 8000 };
1126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(64000, 64000);
1127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // platform allows multiple channels for this format
1128217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
1129217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                sampleRates = new int[] { 8000 };
1130217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = Range.create(13000, 13000);
1131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxChannels = 1;
1132b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AC3)) {
1133b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen                maxChannels = 6;
1134b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_EAC3)) {
1135b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen                maxChannels = 16;
1136217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else {
1137217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Log.w(TAG, "Unsupported mime " + mime);
1138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mParent.mError |= ERROR_UNSUPPORTED;
1139217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1140217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1141217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // restrict ranges
1142217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (sampleRates != null) {
1143217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                limitSampleRates(sampleRates);
1144217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (sampleRateRange != null) {
1145217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                limitSampleRates(new Range[] { sampleRateRange });
1146217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1147217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyLimits(maxChannels, bitRates);
1148217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1149b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1150217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyLimits(int maxInputChannels, Range<Integer> bitRates) {
1151217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mMaxInputChannelCount = Range.create(1, mMaxInputChannelCount)
1152217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    .clamp(maxInputChannels);
1153217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (bitRates != null) {
1154217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mBitrateRange = mBitrateRange.intersect(bitRates);
1155b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1156217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1157217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1158217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void parseFromInfo(MediaFormat info) {
1159217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int maxInputChannels = MAX_INPUT_CHANNEL_COUNT;
1160217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Range<Integer> bitRates = POSITIVE_INTEGERS;
1161b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1162217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (info.containsKey("sample-rate-ranges")) {
1163217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                String[] rateStrings = info.getString("sample-rate-ranges").split(",");
1164217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Range<Integer>[] rateRanges = new Range[rateStrings.length];
1165217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (int i = 0; i < rateStrings.length; i++) {
1166217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    rateRanges[i] = Utils.parseIntRange(rateStrings[i], null);
1167217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1168217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                limitSampleRates(rateRanges);
1169217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1170217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (info.containsKey("max-channel-count")) {
1171217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxInputChannels = Utils.parseIntSafely(
1172217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        info.getString("max-channel-count"), maxInputChannels);
1173f31d11341e689ff5a630350cb48d30ff0ec21e70Robert Shih            } else if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
1174f31d11341e689ff5a630350cb48d30ff0ec21e70Robert Shih                maxInputChannels = 0;
1175217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1176217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (info.containsKey("bitrate-range")) {
1177217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                bitRates = bitRates.intersect(
1178216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                        Utils.parseIntRange(info.getString("bitrate-range"), bitRates));
1179b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1180217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyLimits(maxInputChannels, bitRates);
1181217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1182b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1183217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1184a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang        public void getDefaultFormat(MediaFormat format) {
1185217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // report settings that have only a single choice
1186217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) {
1187217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower());
1188217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1189217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (mMaxInputChannelCount == 1) {
1190217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // mono-only format
1191217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1);
1192217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1193217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (mSampleRates != null && mSampleRates.length == 1) {
1194217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRates[0]);
1195217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1196217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1197217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1198217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1199217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean supportsFormat(MediaFormat format) {
1200217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Map<String, Object> map = format.getMap();
1201217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
1202217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
12030581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
1204217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (!supports(sampleRate, channels)) {
1205217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                return false;
1206217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1207217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
12080581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
12090581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                return false;
12100581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
12110581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
1212217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // nothing to do for:
1213217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // KEY_CHANNEL_MASK: codecs don't get this
1214217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // KEY_IS_ADTS:      required feature for all AAC decoders
1215217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return true;
1216217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1217217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    }
1218217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1219217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    /**
1220217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar     * A class that supports querying the video capabilities of a codec.
1221217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar     */
1222217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    public static final class VideoCapabilities {
1223217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private static final String TAG = "VideoCapabilities";
1224217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private CodecCapabilities mParent;
1225217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mBitrateRange;
1226217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1227217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mHeightRange;
1228217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mWidthRange;
1229217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mBlockCountRange;
1230217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mHorizontalBlockRange;
1231217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mVerticalBlockRange;
1232217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Rational> mAspectRatioRange;
1233217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Rational> mBlockAspectRatioRange;
1234217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Long> mBlocksPerSecondRange;
123575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        private Map<Size, Range<Long>> mMeasuredFrameRates;
1236217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mFrameRateRange;
1237217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1238217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mBlockWidth;
1239217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mBlockHeight;
1240217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mWidthAlignment;
1241217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mHeightAlignment;
1242217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mSmallerDimensionUpperLimit;
1243217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
12442fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar        private boolean mAllowMbOverride; // allow XML to override calculated limits
12452fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
1246217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1247217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported bitrates in bits/second.
1248217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1249217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getBitrateRange() {
1250217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mBitrateRange;
1251217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1252217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1253217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1254217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported video widths.
1255217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1256217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getSupportedWidths() {
1257217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mWidthRange;
1258217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1259217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1260217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1261217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported video heights.
1262217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1263217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getSupportedHeights() {
1264217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mHeightRange;
1265217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1266217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1267217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1268217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the alignment requirement for video width (in pixels).
1269217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         *
1270217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * This is a power-of-2 value that video width must be a
1271217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * multiple of.
1272217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1273217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public int getWidthAlignment() {
1274217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mWidthAlignment;
1275217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1276217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1277217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1278217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the alignment requirement for video height (in pixels).
1279217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         *
1280217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * This is a power-of-2 value that video height must be a
1281217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * multiple of.
1282217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1283217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public int getHeightAlignment() {
1284217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mHeightAlignment;
1285217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1286217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1287217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1288217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Return the upper limit on the smaller dimension of width or height.
1289217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * <p></p>
1290217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Some codecs have a limit on the smaller dimension, whether it be
1291217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * the width or the height.  E.g. a codec may only be able to handle
1292217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * up to 1920x1080 both in landscape and portrait mode (1080x1920).
1293217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * In this case the maximum width and height are both 1920, but the
1294217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * smaller dimension limit will be 1080. For other codecs, this is
1295217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * {@code Math.min(getSupportedWidths().getUpper(),
1296217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * getSupportedHeights().getUpper())}.
1297217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         *
1298217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @hide
1299217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1300217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public int getSmallerDimensionUpperLimit() {
1301217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mSmallerDimensionUpperLimit;
1302217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1303217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1304217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1305217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported frame rates.
1306217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * <p>
1307217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * This is not a performance indicator.  Rather, it expresses the
1308217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * limits specified in the coding standard, based on the complexities
1309217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * of encoding material for later playback at a certain frame rate,
1310217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * or the decoding of such material in non-realtime.
1311217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1312217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getSupportedFrameRates() {
1313217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mFrameRateRange;
1314217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1315217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1316217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1317217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported video widths for a video height.
1318217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @param height the height of the video
1319217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1320217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getSupportedWidthsFor(int height) {
1321217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            try {
1322217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Range<Integer> range = mWidthRange;
1323217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (!mHeightRange.contains(height)
1324217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        || (height % mHeightAlignment) != 0) {
1325217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    throw new IllegalArgumentException("unsupported height");
1326b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1327217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int heightInBlocks = Utils.divUp(height, mBlockHeight);
1328217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1329217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // constrain by block count and by block aspect ratio
1330217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int minWidthInBlocks = Math.max(
1331217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        Utils.divUp(mBlockCountRange.getLower(), heightInBlocks),
1332217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)Math.ceil(mBlockAspectRatioRange.getLower().doubleValue()
1333217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                * heightInBlocks));
1334217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int maxWidthInBlocks = Math.min(
1335217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mBlockCountRange.getUpper() / heightInBlocks,
1336217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)(mBlockAspectRatioRange.getUpper().doubleValue()
1337217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                * heightInBlocks));
1338217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                range = range.intersect(
1339217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (minWidthInBlocks - 1) * mBlockWidth + mWidthAlignment,
1340217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxWidthInBlocks * mBlockWidth);
1341217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1342217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // constrain by smaller dimension limit
1343217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (height > mSmallerDimensionUpperLimit) {
1344217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    range = range.intersect(1, mSmallerDimensionUpperLimit);
1345b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1346b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1347217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // constrain by aspect ratio
1348217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                range = range.intersect(
1349217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)Math.ceil(mAspectRatioRange.getLower().doubleValue()
1350217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                * height),
1351217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)(mAspectRatioRange.getUpper().doubleValue() * height));
1352217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                return range;
1353217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } catch (IllegalArgumentException e) {
13546c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar                // height is not supported because there are no suitable widths
13556c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar                Log.v(TAG, "could not get supported widths for " + height);
1356217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                throw new IllegalArgumentException("unsupported height");
1357b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1358217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1359b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1360217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1361217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported video heights for a video width
1362217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @param width the width of the video
1363217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1364217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getSupportedHeightsFor(int width) {
1365217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            try {
1366217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Range<Integer> range = mHeightRange;
1367217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (!mWidthRange.contains(width)
1368217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        || (width % mWidthAlignment) != 0) {
1369217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    throw new IllegalArgumentException("unsupported width");
1370b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1371217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int widthInBlocks = Utils.divUp(width, mBlockWidth);
1372217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1373217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // constrain by block count and by block aspect ratio
1374217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int minHeightInBlocks = Math.max(
1375217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        Utils.divUp(mBlockCountRange.getLower(), widthInBlocks),
1376217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)Math.ceil(widthInBlocks /
1377217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                mBlockAspectRatioRange.getUpper().doubleValue()));
1378217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int maxHeightInBlocks = Math.min(
1379217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mBlockCountRange.getUpper() / widthInBlocks,
1380217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)(widthInBlocks /
1381217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                mBlockAspectRatioRange.getLower().doubleValue()));
1382217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                range = range.intersect(
1383217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (minHeightInBlocks - 1) * mBlockHeight + mHeightAlignment,
1384217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxHeightInBlocks * mBlockHeight);
1385217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1386217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // constrain by smaller dimension limit
1387217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (width > mSmallerDimensionUpperLimit) {
1388217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    range = range.intersect(1, mSmallerDimensionUpperLimit);
1389217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1390217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1391217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // constrain by aspect ratio
1392217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                range = range.intersect(
1393217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)Math.ceil(width /
1394217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                mAspectRatioRange.getUpper().doubleValue()),
1395217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        (int)(width / mAspectRatioRange.getLower().doubleValue()));
1396217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                return range;
1397217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } catch (IllegalArgumentException e) {
13986c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar                // width is not supported because there are no suitable heights
13996c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar                Log.v(TAG, "could not get supported heights for " + width);
1400217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                throw new IllegalArgumentException("unsupported width");
1401217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1402217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1403217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1404217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1405217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the range of supported video frame rates for a video size.
1406217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * <p>
1407217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * This is not a performance indicator.  Rather, it expresses the limits specified in
1408217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * the coding standard, based on the complexities of encoding material of a given
1409217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * size for later playback at a certain frame rate, or the decoding of such material
1410217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * in non-realtime.
1411217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1412217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @param width the width of the video
1413217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @param height the height of the video
1414217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1415217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Double> getSupportedFrameRatesFor(int width, int height) {
1416217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Range<Integer> range = mHeightRange;
1417217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (!supports(width, height, null)) {
1418217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                throw new IllegalArgumentException("unsupported size");
1419217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1420217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final int blockCount =
1421217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
1422217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1423217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return Range.create(
1424217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Math.max(mBlocksPerSecondRange.getLower() / (double) blockCount,
1425217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            (double) mFrameRateRange.getLower()),
1426217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Math.min(mBlocksPerSecondRange.getUpper() / (double) blockCount,
1427217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            (double) mFrameRateRange.getUpper()));
1428217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1429217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1430e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu        private int getBlockCount(int width, int height) {
1431e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu            return Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight);
1432e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu        }
1433e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu
143475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        @NonNull
143575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        private Size findClosestSize(int width, int height) {
1436e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu            int targetBlockCount = getBlockCount(width, height);
143775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            Size closestSize = null;
1438e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu            int minDiff = Integer.MAX_VALUE;
143975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            for (Size size : mMeasuredFrameRates.keySet()) {
1440e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu                int diff = Math.abs(targetBlockCount -
1441e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu                        getBlockCount(size.getWidth(), size.getHeight()));
1442e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu                if (diff < minDiff) {
1443e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu                    minDiff = diff;
144475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                    closestSize = size;
144575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                }
144675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            }
144775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            return closestSize;
144875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        }
144975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu
145075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        private Range<Double> estimateFrameRatesFor(int width, int height) {
145175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            Size size = findClosestSize(width, height);
145275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            Range<Long> range = mMeasuredFrameRates.get(size);
14537a2ab16b65f7ae252a7b127a7286f6ecde87bdf0Lajos Molnar            Double ratio = getBlockCount(size.getWidth(), size.getHeight())
14547a2ab16b65f7ae252a7b127a7286f6ecde87bdf0Lajos Molnar                    / (double)Math.max(getBlockCount(width, height), 1);
145575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            return Range.create(range.getLower() * ratio, range.getUpper() * ratio);
145675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        }
145775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu
1458217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
145938a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * Returns the range of achievable video frame rates for a video size.
146038a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * May return {@code null}, if the codec did not publish any measurement
146138a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * data.
146238a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * <p>
1463b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * This is a performance estimate provided by the device manufacturer based on statistical
1464b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * sampling of full-speed decoding and encoding measurements in various configurations
1465afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * of common video sizes supported by the codec. As such it should only be used to
1466afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * compare individual codecs on the device. The value is not suitable for comparing
1467afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * different devices or even different android releases for the same device.
1468afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * <p>
1469b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * <em>On {@link android.os.Build.VERSION_CODES#M} release</em> the returned range
1470b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * corresponds to the fastest frame rates achieved in the tested configurations. As
1471b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * such, it should not be used to gauge guaranteed or even average codec performance
1472b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * on the device.
1473b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * <p>
1474b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * <em>On {@link android.os.Build.VERSION_CODES#N} release</em> the returned range
1475b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * corresponds closer to sustained performance <em>in tested configurations</em>.
1476b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * One can expect to achieve sustained performance higher than the lower limit more than
1477b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * 50% of the time, and higher than half of the lower limit at least 90% of the time
1478b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * <em>in tested configurations</em>.
1479b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * Conversely, one can expect performance lower than twice the upper limit at least
1480b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * 90% of the time.
1481b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * <p class=note>
1482b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * Tested configurations use a single active codec. For use cases where multiple
1483b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * codecs are active, applications can expect lower and in most cases significantly lower
1484b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * performance.
1485b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * <p class=note>
1486b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * The returned range value is interpolated from the nearest frame size(s) tested.
1487b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * Codec performance is severely impacted by other activity on the device as well
1488b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * as environmental factors (such as battery level, temperature or power source), and can
1489b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar         * vary significantly even in a steady environment.
1490afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * <p class=note>
1491afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * Use this method in cases where only codec performance matters, e.g. to evaluate if
1492afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * a codec has any chance of meeting a performance target. Codecs are listed
1493afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * in {@link MediaCodecList} in the preferred order as defined by the device
1494afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * manufacturer. As such, applications should use the first suitable codec in the
1495afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar         * list to achieve the best balance between power use and performance.
149638a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         *
149738a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * @param width the width of the video
149838a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * @param height the height of the video
149938a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         *
150038a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         * @throws IllegalArgumentException if the video size is not supported.
150138a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar         */
150275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        @Nullable
150338a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar        public Range<Double> getAchievableFrameRatesFor(int width, int height) {
150438a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar            if (!supports(width, height, null)) {
150538a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar                throw new IllegalArgumentException("unsupported size");
150638a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar            }
150775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu
150875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            if (mMeasuredFrameRates == null || mMeasuredFrameRates.size() <= 0) {
150975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                Log.w(TAG, "Codec did not publish any measurement data.");
151075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                return null;
151175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            }
151275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu
151375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            return estimateFrameRatesFor(width, height);
151438a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar        }
151538a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar
151638a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar        /**
1517217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns whether a given video size ({@code width} and
1518217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * {@code height}) and {@code frameRate} combination is supported.
1519217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1520217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean areSizeAndRateSupported(
1521217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int width, int height, double frameRate) {
1522217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return supports(width, height, frameRate);
1523217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1524217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1525217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1526217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns whether a given video size ({@code width} and
1527217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * {@code height}) is supported.
1528217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
1529217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean isSizeSupported(int width, int height) {
1530217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return supports(width, height, null);
1531217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1532217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
15330581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar        private boolean supports(Integer width, Integer height, Number rate) {
1534217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            boolean ok = true;
1535217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1536217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && width != null) {
1537217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = mWidthRange.contains(width)
1538217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        && (width % mWidthAlignment == 0);
1539217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1540217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && height != null) {
1541217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = mHeightRange.contains(height)
1542217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        && (height % mHeightAlignment == 0);
1543b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1544217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && rate != null) {
1545a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar                ok = mFrameRateRange.contains(Utils.intRangeFor(rate.doubleValue()));
1546217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1547217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && height != null && width != null) {
1548217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = Math.min(height, width) <= mSmallerDimensionUpperLimit;
1549b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1550217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int widthInBlocks = Utils.divUp(width, mBlockWidth);
1551217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int heightInBlocks = Utils.divUp(height, mBlockHeight);
1552217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                final int blockCount = widthInBlocks * heightInBlocks;
1553217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = ok && mBlockCountRange.contains(blockCount)
1554217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        && mBlockAspectRatioRange.contains(
1555217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                new Rational(widthInBlocks, heightInBlocks))
1556217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        && mAspectRatioRange.contains(new Rational(width, height));
1557217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (ok && rate != null) {
1558a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar                    double blocksPerSec = blockCount * rate.doubleValue();
1559217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    ok = mBlocksPerSecondRange.contains(
1560217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.longRangeFor(blocksPerSec));
1561b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1562b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1563217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return ok;
1564217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1565b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1566217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
1567217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @hide
1568217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * @throws java.lang.ClassCastException */
1569217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean supportsFormat(MediaFormat format) {
1570217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final Map<String, Object> map = format.getMap();
1571217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer width = (Integer)map.get(MediaFormat.KEY_WIDTH);
1572217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
1573a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar            Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE);
1574217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
15750581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            if (!supports(width, height, rate)) {
15760581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                return false;
15770581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
1578217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
15790581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
15800581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar                return false;
15810581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            }
15820581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar
15830581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            // we ignore color-format for now as it is not reliably reported by codec
15840581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar            return true;
1585217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1586217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1587217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /* no public constructor */
1588217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private VideoCapabilities() { }
1589217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1590217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1591217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public static VideoCapabilities create(
1592217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                MediaFormat info, CodecCapabilities parent) {
1593217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            VideoCapabilities caps = new VideoCapabilities();
1594217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            caps.init(info, parent);
1595217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return caps;
1596217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1597217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1598a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang        private void init(MediaFormat info, CodecCapabilities parent) {
1599217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mParent = parent;
1600217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            initWithPlatformLimits();
1601217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyLevelLimits();
1602217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            parseFromInfo(info);
1603217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            updateLimits();
1604217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1605217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1606217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1607217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Size getBlockSize() {
1608217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return new Size(mBlockWidth, mBlockHeight);
1609217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1610217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1611217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1612217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getBlockCountRange() {
1613217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mBlockCountRange;
1614217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1615217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1616217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1617217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Long> getBlocksPerSecondRange() {
1618217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mBlocksPerSecondRange;
1619217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1620b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1621217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
1622217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Rational> getAspectRatioRange(boolean blocks) {
1623217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return blocks ? mBlockAspectRatioRange : mAspectRatioRange;
1624217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1625217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1626217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void initWithPlatformLimits() {
1627216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang            mBitrateRange = BITRATE_RANGE;
1628217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1629217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mWidthRange  = SIZE_RANGE;
1630217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHeightRange = SIZE_RANGE;
1631217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mFrameRateRange = FRAME_RATE_RANGE;
1632217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1633217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHorizontalBlockRange = SIZE_RANGE;
1634217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mVerticalBlockRange   = SIZE_RANGE;
1635217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1636217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // full positive ranges are supported as these get calculated
1637217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockCountRange      = POSITIVE_INTEGERS;
1638217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlocksPerSecondRange = POSITIVE_LONGS;
1639217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1640217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockAspectRatioRange = POSITIVE_RATIONALS;
1641217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mAspectRatioRange      = POSITIVE_RATIONALS;
1642217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1643217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // YUV 4:2:0 requires 2:2 alignment
1644217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mWidthAlignment = 2;
1645217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHeightAlignment = 2;
1646217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockWidth = 2;
1647217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockHeight = 2;
1648217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper();
1649217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1650217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
165175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        private Map<Size, Range<Long>> getMeasuredFrameRates(Map<String, Object> map) {
165275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            Map<Size, Range<Long>> ret = new HashMap<Size, Range<Long>>();
165375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            final String prefix = "measured-frame-rate-";
165475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            Set<String> keys = map.keySet();
165575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            for (String key : keys) {
165675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                // looking for: measured-frame-rate-WIDTHxHEIGHT-range
165775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                if (!key.startsWith(prefix)) {
165875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                    continue;
165975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                }
166075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                String subKey = key.substring(prefix.length());
166175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                String[] temp = key.split("-");
166275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                if (temp.length != 5) {
166375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                    continue;
166475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                }
166575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                String sizeStr = temp[3];
166675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                Size size = Utils.parseSize(sizeStr, null);
166775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                if (size == null || size.getWidth() * size.getHeight() <= 0) {
166875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                    continue;
166975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                }
167075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                Range<Long> range = Utils.parseLongRange(map.get(key), null);
167175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                if (range == null || range.getLower() < 0 || range.getUpper() < 0) {
167275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                    continue;
167375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                }
167475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu                ret.put(size, range);
167575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            }
167675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            return ret;
167775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu        }
167875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu
16798acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar        private static Pair<Range<Integer>, Range<Integer>> parseWidthHeightRanges(Object o) {
16808acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Pair<Size, Size> range = Utils.parseSizeRange(o);
16818acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (range != null) {
16828acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                try {
16838acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    return Pair.create(
16848acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            Range.create(range.first.getWidth(), range.second.getWidth()),
16858acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            Range.create(range.first.getHeight(), range.second.getHeight()));
16868acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                } catch (IllegalArgumentException e) {
16878acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    Log.w(TAG, "could not parse size range '" + o + "'");
16888acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                }
16898acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            }
16908acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            return null;
16918acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar        }
16928acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
16938acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar        /** @hide */
16948acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar        public static int equivalentVP9Level(MediaFormat info) {
16958acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            final Map<String, Object> map = info.getMap();
16968acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
16978acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Size blockSize = Utils.parseSize(map.get("block-size"), new Size(8, 8));
16988acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            int BS = blockSize.getWidth() * blockSize.getHeight();
16998acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
17008acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Range<Integer> counts = Utils.parseIntRange(map.get("block-count-range"), null);
17018acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            int FS = counts == null ? 0 : BS * counts.getUpper();
17028acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
17038acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Range<Long> blockRates =
17048acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                Utils.parseLongRange(map.get("blocks-per-second-range"), null);
17058acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            long SR = blockRates == null ? 0 : BS * blockRates.getUpper();
17068acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
17078acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Pair<Range<Integer>, Range<Integer>> dimensionRanges =
17088acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                parseWidthHeightRanges(map.get("size-range"));
17098acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            int D = dimensionRanges == null ? 0 : Math.max(
17108acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    dimensionRanges.first.getUpper(), dimensionRanges.second.getUpper());
17118acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
17128acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Range<Integer> bitRates = Utils.parseIntRange(map.get("bitrate-range"), null);
17138acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            int BR = bitRates == null ? 0 : Utils.divUp(bitRates.getUpper(), 1000);
17148acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
17158acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=      829440 && FS <=    36864 && BR <=    200 && D <=   512)
17168acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level1;
17178acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=     2764800 && FS <=    73728 && BR <=    800 && D <=   768)
17188acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level11;
17198acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=     4608000 && FS <=   122880 && BR <=   1800 && D <=   960)
17208acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level2;
17218acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=     9216000 && FS <=   245760 && BR <=   3600 && D <=  1344)
17228acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level21;
17238acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=    20736000 && FS <=   552960 && BR <=   7200 && D <=  2048)
17248acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level3;
17258acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=    36864000 && FS <=   983040 && BR <=  12000 && D <=  2752)
17268acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level31;
17278acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=    83558400 && FS <=  2228224 && BR <=  18000 && D <=  4160)
17288acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level4;
17298acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=   160432128 && FS <=  2228224 && BR <=  30000 && D <=  4160)
17308acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level41;
17318acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=   311951360 && FS <=  8912896 && BR <=  60000 && D <=  8384)
17328acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level5;
17338acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=   588251136 && FS <=  8912896 && BR <= 120000 && D <=  8384)
17348acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level51;
17358acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=  1176502272 && FS <=  8912896 && BR <= 180000 && D <=  8384)
17368acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level52;
17378acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <=  1176502272 && FS <= 35651584 && BR <= 180000 && D <= 16832)
17388acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level6;
17398acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <= 2353004544L && FS <= 35651584 && BR <= 240000 && D <= 16832)
17408acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level61;
17418acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (SR <= 4706009088L && FS <= 35651584 && BR <= 480000 && D <= 16832)
17428acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                return CodecProfileLevel.VP9Level62;
17438acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            // returning largest level
17448acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            return CodecProfileLevel.VP9Level62;
17458acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar        }
17468acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar
1747217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void parseFromInfo(MediaFormat info) {
1748217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final Map<String, Object> map = info.getMap();
1749217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Size blockSize = new Size(mBlockWidth, mBlockHeight);
1750217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Size alignment = new Size(mWidthAlignment, mHeightAlignment);
1751217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Range<Integer> counts = null, widths = null, heights = null;
1752216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang            Range<Integer> frameRates = null, bitRates = null;
1753217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Range<Long> blockRates = null;
1754217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Range<Rational> ratios = null, blockRatios = null;
1755217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1756217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            blockSize = Utils.parseSize(map.get("block-size"), blockSize);
1757217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            alignment = Utils.parseSize(map.get("alignment"), alignment);
1758217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            counts = Utils.parseIntRange(map.get("block-count-range"), null);
1759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            blockRates =
1760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Utils.parseLongRange(map.get("blocks-per-second-range"), null);
176175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu            mMeasuredFrameRates = getMeasuredFrameRates(map);
17628acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            Pair<Range<Integer>, Range<Integer>> sizeRanges =
17638acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                parseWidthHeightRanges(map.get("size-range"));
17648acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar            if (sizeRanges != null) {
17658acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                widths = sizeRanges.first;
17668acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                heights = sizeRanges.second;
1767b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // for now this just means using the smaller max size as 2nd
1769217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // upper limit.
1770217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // for now we are keeping the profile specific "width/height
1771217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // in macroblocks" limits.
17721c436bd911373810b2ac14088dd16762daf94191Lajos Molnar            if (map.containsKey("feature-can-swap-width-height")) {
1773217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (widths != null) {
1774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mSmallerDimensionUpperLimit =
1775217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        Math.min(widths.getUpper(), heights.getUpper());
1776217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    widths = heights = widths.extend(heights);
1777981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar                } else {
1778217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Log.w(TAG, "feature can-swap-width-height is best used with size-range");
1779217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mSmallerDimensionUpperLimit =
1780217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        Math.min(mWidthRange.getUpper(), mHeightRange.getUpper());
1781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange);
1782b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1783b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1784b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1785217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            ratios = Utils.parseRationalRange(
1786217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    map.get("block-aspect-ratio-range"), null);
1787217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            blockRatios = Utils.parseRationalRange(
1788217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    map.get("pixel-aspect-ratio-range"), null);
1789217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            frameRates = Utils.parseIntRange(map.get("frame-rate-range"), null);
1790217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (frameRates != null) {
1791217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                try {
1792217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    frameRates = frameRates.intersect(FRAME_RATE_RANGE);
1793217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                } catch (IllegalArgumentException e) {
1794217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Log.w(TAG, "frame rate range (" + frameRates
1795217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            + ") is out of limits: " + FRAME_RATE_RANGE);
1796217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    frameRates = null;
1797b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1798b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1799216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang            bitRates = Utils.parseIntRange(map.get("bitrate-range"), null);
1800216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang            if (bitRates != null) {
1801216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                try {
1802216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                    bitRates = bitRates.intersect(BITRATE_RANGE);
1803216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                } catch (IllegalArgumentException e) {
1804216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                    Log.w(TAG,  "bitrate range (" + bitRates
1805216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                            + ") is out of limits: " + BITRATE_RANGE);
1806216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                    bitRates = null;
1807216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                }
1808216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang            }
1809b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1810217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(
1811217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    blockSize.getWidth(), "block-size width must be power of two");
1812217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(
1813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    blockSize.getHeight(), "block-size height must be power of two");
1814b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(
1816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    alignment.getWidth(), "alignment width must be power of two");
1817217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(
1818217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    alignment.getHeight(), "alignment height must be power of two");
1819217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1820217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // update block-size and alignment
1821217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyMacroBlockLimits(
1822217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE,
1823217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(),
1824217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    alignment.getWidth(), alignment.getHeight());
1825217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
18262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar            if ((mParent.mError & ERROR_UNSUPPORTED) != 0 || mAllowMbOverride) {
1827217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // codec supports profiles that we don't know.
1828217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // Use supplied values clipped to platform limits
1829217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (widths != null) {
1830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mWidthRange = SIZE_RANGE.intersect(widths);
1831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1832217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (heights != null) {
1833217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mHeightRange = SIZE_RANGE.intersect(heights);
1834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1835217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (counts != null) {
1836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlockCountRange = POSITIVE_INTEGERS.intersect(
1837217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.factorRange(counts, mBlockWidth * mBlockHeight
1838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    / blockSize.getWidth() / blockSize.getHeight()));
1839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (blockRates != null) {
1841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlocksPerSecondRange = POSITIVE_LONGS.intersect(
1842217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
1843217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    / blockSize.getWidth() / blockSize.getHeight()));
1844217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1845217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (blockRatios != null) {
1846217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect(
1847217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.scaleRange(blockRatios,
1848217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    mBlockHeight / blockSize.getHeight(),
1849217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    mBlockWidth / blockSize.getWidth()));
1850217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1851217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (ratios != null) {
1852217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios);
1853217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1854217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (frameRates != null) {
1855217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates);
1856217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1857216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                if (bitRates != null) {
18582fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    // only allow bitrate override if unsupported profiles were encountered
18592fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
18602fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        mBitrateRange = BITRATE_RANGE.intersect(bitRates);
18612fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    } else {
18622fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        mBitrateRange = mBitrateRange.intersect(bitRates);
18632fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    }
1864216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                }
1865217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else {
1866217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // no unsupported profile/levels, so restrict values to known limits
1867217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (widths != null) {
1868217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mWidthRange = mWidthRange.intersect(widths);
1869217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1870217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (heights != null) {
1871217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mHeightRange = mHeightRange.intersect(heights);
1872b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1873217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (counts != null) {
1874217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlockCountRange = mBlockCountRange.intersect(
1875217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.factorRange(counts, mBlockWidth * mBlockHeight
1876217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    / blockSize.getWidth() / blockSize.getHeight()));
1877b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1878217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (blockRates != null) {
1879217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
1880217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.factorRange(blockRates, mBlockWidth * mBlockHeight
1881217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    / blockSize.getWidth() / blockSize.getHeight()));
1882b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
1883217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (blockRatios != null) {
1884217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
1885217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Utils.scaleRange(blockRatios,
1886217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    mBlockHeight / blockSize.getHeight(),
1887217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    mBlockWidth / blockSize.getWidth()));
1888217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1889217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (ratios != null) {
1890217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mAspectRatioRange = mAspectRatioRange.intersect(ratios);
1891217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1892217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (frameRates != null) {
1893217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mFrameRateRange = mFrameRateRange.intersect(frameRates);
1894217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
1895216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                if (bitRates != null) {
1896216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                    mBitrateRange = mBitrateRange.intersect(bitRates);
1897216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang                }
1898217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1899217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            updateLimits();
1900217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1901217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1902217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyBlockLimits(
1903217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int blockWidth, int blockHeight,
1904217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Range<Integer> counts, Range<Long> rates, Range<Rational> ratios) {
1905217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(blockWidth, "blockWidth must be a power of two");
1906217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(blockHeight, "blockHeight must be a power of two");
1907217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1908217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final int newBlockWidth = Math.max(blockWidth, mBlockWidth);
1909217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final int newBlockHeight = Math.max(blockHeight, mBlockHeight);
1910217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1911217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // factor will always be a power-of-2
1912217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int factor =
1913217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight;
1914217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (factor != 1) {
1915217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mBlockCountRange = Utils.factorRange(mBlockCountRange, factor);
1916217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mBlocksPerSecondRange = Utils.factorRange(
1917217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mBlocksPerSecondRange, factor);
1918217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mBlockAspectRatioRange = Utils.scaleRange(
1919217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mBlockAspectRatioRange,
1920217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        newBlockHeight / mBlockHeight,
1921217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        newBlockWidth / mBlockWidth);
1922217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mHorizontalBlockRange = Utils.factorRange(
1923217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mHorizontalBlockRange, newBlockWidth / mBlockWidth);
1924217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mVerticalBlockRange = Utils.factorRange(
1925217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        mVerticalBlockRange, newBlockHeight / mBlockHeight);
1926217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1927217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight;
1928217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (factor != 1) {
1929217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                counts = Utils.factorRange(counts, factor);
1930217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                rates = Utils.factorRange(rates, factor);
1931217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ratios = Utils.scaleRange(
1932217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        ratios, newBlockHeight / blockHeight,
1933217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        newBlockWidth / blockWidth);
1934217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
1935217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockCountRange = mBlockCountRange.intersect(counts);
1936217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates);
1937217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios);
1938217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockWidth = newBlockWidth;
1939217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockHeight = newBlockHeight;
1940217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1941217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1942217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyAlignment(int widthAlignment, int heightAlignment) {
1943217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(widthAlignment, "widthAlignment must be a power of two");
1944217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            checkPowerOfTwo(heightAlignment, "heightAlignment must be a power of two");
1945217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1946217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) {
1947217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // maintain assumption that 0 < alignment <= block-size
1948217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                applyBlockLimits(
1949217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        Math.max(widthAlignment, mBlockWidth),
1950217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        Math.max(heightAlignment, mBlockHeight),
1951217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        POSITIVE_INTEGERS, POSITIVE_LONGS, POSITIVE_RATIONALS);
1952b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
1953b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
1954217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mWidthAlignment = Math.max(widthAlignment, mWidthAlignment);
1955217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHeightAlignment = Math.max(heightAlignment, mHeightAlignment);
1956217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1957217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mWidthRange = Utils.alignRange(mWidthRange, mWidthAlignment);
1958217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHeightRange = Utils.alignRange(mHeightRange, mHeightAlignment);
1959217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
1960217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1961217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void updateLimits() {
1962217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // pixels -> blocks <- counts
1963217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHorizontalBlockRange = mHorizontalBlockRange.intersect(
1964217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Utils.factorRange(mWidthRange, mBlockWidth));
1965217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHorizontalBlockRange = mHorizontalBlockRange.intersect(
1966217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Range.create(
1967217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mBlockCountRange.getLower() / mVerticalBlockRange.getUpper(),
1968217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mBlockCountRange.getUpper() / mVerticalBlockRange.getLower()));
1969217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mVerticalBlockRange = mVerticalBlockRange.intersect(
1970217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Utils.factorRange(mHeightRange, mBlockHeight));
1971217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mVerticalBlockRange = mVerticalBlockRange.intersect(
1972217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Range.create(
1973217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mBlockCountRange.getLower() / mHorizontalBlockRange.getUpper(),
1974217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mBlockCountRange.getUpper() / mHorizontalBlockRange.getLower()));
1975217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockCountRange = mBlockCountRange.intersect(
1976217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Range.create(
1977217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mHorizontalBlockRange.getLower()
1978217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    * mVerticalBlockRange.getLower(),
1979217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mHorizontalBlockRange.getUpper()
1980217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    * mVerticalBlockRange.getUpper()));
1981217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(
1982217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    new Rational(
1983217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mHorizontalBlockRange.getLower(), mVerticalBlockRange.getUpper()),
1984217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    new Rational(
1985217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            mHorizontalBlockRange.getUpper(), mVerticalBlockRange.getLower()));
1986217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1987217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // blocks -> pixels
1988217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mWidthRange = mWidthRange.intersect(
1989217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    (mHorizontalBlockRange.getLower() - 1) * mBlockWidth + mWidthAlignment,
1990217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mHorizontalBlockRange.getUpper() * mBlockWidth);
1991217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHeightRange = mHeightRange.intersect(
1992217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    (mVerticalBlockRange.getLower() - 1) * mBlockHeight + mHeightAlignment,
1993217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mVerticalBlockRange.getUpper() * mBlockHeight);
1994217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mAspectRatioRange = mAspectRatioRange.intersect(
1995217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    new Rational(mWidthRange.getLower(), mHeightRange.getUpper()),
1996217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    new Rational(mWidthRange.getUpper(), mHeightRange.getLower()));
1997217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
1998217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mSmallerDimensionUpperLimit = Math.min(
1999217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mSmallerDimensionUpperLimit,
2000217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Math.min(mWidthRange.getUpper(), mHeightRange.getUpper()));
2001217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2002217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // blocks -> rate
2003217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(
2004217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlockCountRange.getLower() * (long)mFrameRateRange.getLower(),
2005217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mBlockCountRange.getUpper() * (long)mFrameRateRange.getUpper());
2006217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mFrameRateRange = mFrameRateRange.intersect(
2007217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    (int)(mBlocksPerSecondRange.getLower()
2008217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            / mBlockCountRange.getUpper()),
2009217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    (int)(mBlocksPerSecondRange.getUpper()
2010217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            / (double)mBlockCountRange.getLower()));
2011217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2012217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2013217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyMacroBlockLimits(
2014217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int maxHorizontalBlocks, int maxVerticalBlocks,
2015217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int maxBlocks, long maxBlocksPerSecond,
2016217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int blockWidth, int blockHeight,
2017217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int widthAlignment, int heightAlignment) {
20182fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar            applyMacroBlockLimits(
20192fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    1 /* minHorizontalBlocks */, 1 /* minVerticalBlocks */,
20202fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    maxHorizontalBlocks, maxVerticalBlocks,
20212fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    maxBlocks, maxBlocksPerSecond,
20222fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    blockWidth, blockHeight, widthAlignment, heightAlignment);
20232fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar        }
20242fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
20252fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar        private void applyMacroBlockLimits(
20262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int minHorizontalBlocks, int minVerticalBlocks,
20272fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int maxHorizontalBlocks, int maxVerticalBlocks,
20282fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int maxBlocks, long maxBlocksPerSecond,
20292fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int blockWidth, int blockHeight,
20302fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int widthAlignment, int heightAlignment) {
2031217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyAlignment(widthAlignment, heightAlignment);
2032217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyBlockLimits(
2033217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    blockWidth, blockHeight, Range.create(1, maxBlocks),
2034217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Range.create(1L, maxBlocksPerSecond),
2035217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    Range.create(
2036217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            new Rational(1, maxVerticalBlocks),
2037217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            new Rational(maxHorizontalBlocks, 1)));
2038217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mHorizontalBlockRange =
2039217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mHorizontalBlockRange.intersect(
20402fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            Utils.divUp(minHorizontalBlocks, (mBlockWidth / blockWidth)),
20412fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            maxHorizontalBlocks / (mBlockWidth / blockWidth));
2042217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mVerticalBlockRange =
2043217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    mVerticalBlockRange.intersect(
20442fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            Utils.divUp(minVerticalBlocks, (mBlockHeight / blockHeight)),
20452fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            maxVerticalBlocks / (mBlockHeight / blockHeight));
2046217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2047217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2048217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyLevelLimits() {
2049f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu            long maxBlocksPerSecond = 0;
2050217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int maxBlocks = 0;
2051217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int maxBps = 0;
2052217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int maxDPBBlocks = 0;
2053217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2054217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            int errors = ERROR_NONE_SUPPORTED;
2055217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            CodecProfileLevel[] profileLevels = mParent.profileLevels;
2056217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            String mime = mParent.getMimeType();
2057217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
20585755817422700f6f5e8380921d1f5a728b677dd2Ronghua Wu            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) {
2059217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocks = 99;
2060217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocksPerSecond = 1485;
2061217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBps = 64000;
2062217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxDPBBlocks = 396;
2063217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (CodecProfileLevel profileLevel: profileLevels) {
2064217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    int MBPS = 0, FS = 0, BR = 0, DPB = 0;
2065217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    boolean supported = true;
2066217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.level) {
2067217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel1:
2068217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =    1485; FS =    99; BR =     64; DPB =    396; break;
2069217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel1b:
2070217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =    1485; FS =    99; BR =    128; DPB =    396; break;
2071217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel11:
2072217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =    3000; FS =   396; BR =    192; DPB =    900; break;
2073217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel12:
2074217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =    6000; FS =   396; BR =    384; DPB =   2376; break;
2075217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel13:
2076217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =   11880; FS =   396; BR =    768; DPB =   2376; break;
2077217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel2:
2078217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =   11880; FS =   396; BR =   2000; DPB =   2376; break;
2079217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel21:
2080217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =   19800; FS =   792; BR =   4000; DPB =   4752; break;
2081217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel22:
2082217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =   20250; FS =  1620; BR =   4000; DPB =   8100; break;
2083217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel3:
2084217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =   40500; FS =  1620; BR =  10000; DPB =   8100; break;
2085217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel31:
2086217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  108000; FS =  3600; BR =  14000; DPB =  18000; break;
2087217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel32:
2088217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  216000; FS =  5120; BR =  20000; DPB =  20480; break;
2089217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel4:
2090217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  245760; FS =  8192; BR =  20000; DPB =  32768; break;
2091217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel41:
2092217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  245760; FS =  8192; BR =  50000; DPB =  32768; break;
2093217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel42:
2094217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  522240; FS =  8704; BR =  50000; DPB =  34816; break;
2095217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel5:
2096217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  589824; FS = 22080; BR = 135000; DPB = 110400; break;
2097217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel51:
2098217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS =  983040; FS = 36864; BR = 240000; DPB = 184320; break;
2099217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCLevel52:
2100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break;
2101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized level "
2103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.level + " for " + mime);
2104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.profile) {
21070aeb1875e472451bb4a2606971ac6c4159e25009Lajos Molnar                        case CodecProfileLevel.AVCProfileConstrainedHigh:
2108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileHigh:
2109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            BR *= 1250; break;
2110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileHigh10:
2111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            BR *= 3000; break;
2112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileExtended:
2113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileHigh422:
2114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileHigh444:
2115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unsupported profile "
2116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNSUPPORTED;
2118217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            supported = false;
2119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            // fall through - treat as base profile
21200aeb1875e472451bb4a2606971ac6c4159e25009Lajos Molnar                        case CodecProfileLevel.AVCProfileConstrainedBaseline:
2121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileBaseline:
2122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.AVCProfileMain:
2123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            BR *= 1000; break;
2124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized profile "
2126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2128217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            BR *= 1000;
2129217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2130217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    if (supported) {
2131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        errors &= ~ERROR_NONE_SUPPORTED;
2132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
2134217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocks = Math.max(FS, maxBlocks);
2135217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBps = Math.max(BR, maxBps);
2136217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxDPBBlocks = Math.max(maxDPBBlocks, DPB);
2137981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar                }
2138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2139217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
2140217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                applyMacroBlockLimits(
2141217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxLengthInBlocks, maxLengthInBlocks,
2142217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxBlocks, maxBlocksPerSecond,
2143217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        16 /* blockWidth */, 16 /* blockHeight */,
2144217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        1 /* widthAlignment */, 1 /* heightAlignment */);
214534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG2)) {
214634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                int maxWidth = 11, maxHeight = 9, maxRate = 15;
214734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                maxBlocks = 99;
214834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                maxBlocksPerSecond = 1485;
214934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                maxBps = 64000;
215034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                for (CodecProfileLevel profileLevel: profileLevels) {
215134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
215234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    boolean supported = true;
215334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    switch (profileLevel.profile) {
215434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        case CodecProfileLevel.MPEG2ProfileSimple:
215534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            switch (profileLevel.level) {
215634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                case CodecProfileLevel.MPEG2LevelML:
21572fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                    FR = 30; W = 45; H =  36; MBPS =  40500; FS =  1620; BR =  15000; break;
215834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                default:
215934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                    Log.w(TAG, "Unrecognized profile/level "
216034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                            + profileLevel.profile + "/"
216134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                            + profileLevel.level + " for " + mime);
216234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                    errors |= ERROR_UNRECOGNIZED;
216334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            }
216434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            break;
216534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        case CodecProfileLevel.MPEG2ProfileMain:
216634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            switch (profileLevel.level) {
216734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                case CodecProfileLevel.MPEG2LevelLL:
21682a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 30; W = 22; H =  18; MBPS =  11880; FS =   396; BR =  4000; break;
216934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                case CodecProfileLevel.MPEG2LevelML:
21702fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                    FR = 30; W = 45; H =  36; MBPS =  40500; FS =  1620; BR = 15000; break;
217134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                case CodecProfileLevel.MPEG2LevelH14:
21722a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 60; W = 90; H =  68; MBPS = 183600; FS =  6120; BR = 60000; break;
217334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                case CodecProfileLevel.MPEG2LevelHL:
21742a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 60; W = 120; H = 68; MBPS = 244800; FS =  8160; BR = 80000; break;
21752a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                case CodecProfileLevel.MPEG2LevelHP:
21762a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 60; W = 120; H = 68; MBPS = 489600; FS =  8160; BR = 80000; break;
217734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                default:
217834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                    Log.w(TAG, "Unrecognized profile/level "
217934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                            + profileLevel.profile + "/"
218034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                            + profileLevel.level + " for " + mime);
218134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                    errors |= ERROR_UNRECOGNIZED;
218234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            }
218334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            break;
218434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        case CodecProfileLevel.MPEG2Profile422:
218534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        case CodecProfileLevel.MPEG2ProfileSNR:
218634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        case CodecProfileLevel.MPEG2ProfileSpatial:
218734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        case CodecProfileLevel.MPEG2ProfileHigh:
218834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            Log.i(TAG, "Unsupported profile "
218934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                    + profileLevel.profile + " for " + mime);
219034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            errors |= ERROR_UNSUPPORTED;
219134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            supported = false;
219234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            break;
219334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        default:
219434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            Log.w(TAG, "Unrecognized profile "
219534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                                    + profileLevel.profile + " for " + mime);
219634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                            errors |= ERROR_UNRECOGNIZED;
219734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    }
219834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    if (supported) {
219934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        errors &= ~ERROR_NONE_SUPPORTED;
220034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    }
220134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
220234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    maxBlocks = Math.max(FS, maxBlocks);
220334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    maxBps = Math.max(BR * 1000, maxBps);
220434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    maxWidth = Math.max(W, maxWidth);
220534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    maxHeight = Math.max(H, maxHeight);
220634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                    maxRate = Math.max(FR, maxRate);
220734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                }
220834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                applyMacroBlockLimits(maxWidth, maxHeight,
220934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        maxBlocks, maxBlocksPerSecond,
221034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        16 /* blockWidth */, 16 /* blockHeight */,
221134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                        1 /* widthAlignment */, 1 /* heightAlignment */);
221234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar                mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
2213217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
2214217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int maxWidth = 11, maxHeight = 9, maxRate = 15;
2215217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocks = 99;
2216217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocksPerSecond = 1485;
2217217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBps = 64000;
2218217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (CodecProfileLevel profileLevel: profileLevels) {
2219217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
22202fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    boolean strict = false; // true: W, H and FR are individual max limits
2221217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    boolean supported = true;
2222217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.profile) {
2223217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileSimple:
2224217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            switch (profileLevel.level) {
2225217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level0:
22262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                    strict = true;
2227217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
2228217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level1:
2229217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 11; H =  9; MBPS =  1485; FS =  99; BR =  64; break;
2230217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level0b:
22312fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                    strict = true;
22322fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                    FR = 15; W = 11; H =  9; MBPS =  1485; FS =  99; BR = 128; break;
2233217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level2:
2234217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 22; H = 18; MBPS =  5940; FS = 396; BR = 128; break;
2235217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level3:
2236217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break;
2237217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level4a:
22382a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 30; W = 40; H = 30; MBPS = 36000; FS = 1200; BR = 4000; break;
2239217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level5:
22402a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 8000; break;
22412a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                case CodecProfileLevel.MPEG4Level6:
22422a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 30; W = 80; H = 45; MBPS = 108000; FS = 3600; BR = 12000; break;
2243217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                default:
2244217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    Log.w(TAG, "Unrecognized profile/level "
2245217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                            + profileLevel.profile + "/"
2246217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                            + profileLevel.level + " for " + mime);
2247217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    errors |= ERROR_UNRECOGNIZED;
2248217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            }
2249217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2250217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileAdvancedSimple:
2251217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            switch (profileLevel.level) {
2252217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level0:
2253217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level1:
2254217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 11; H =  9; MBPS =  2970; FS =   99; BR =  128; break;
2255217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level2:
2256217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 22; H = 18; MBPS =  5940; FS =  396; BR =  384; break;
2257217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level3:
2258217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR =  768; break;
22592a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                case CodecProfileLevel.MPEG4Level3b:
22602a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar                                    FR = 30; W = 22; H = 18; MBPS = 11880; FS =  396; BR = 1500; break;
2261217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level4:
2262217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 44; H = 36; MBPS = 23760; FS =  792; BR = 3000; break;
2263217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                case CodecProfileLevel.MPEG4Level5:
2264217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break;
2265217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                default:
2266217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    Log.w(TAG, "Unrecognized profile/level "
2267217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                            + profileLevel.profile + "/"
2268217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                            + profileLevel.level + " for " + mime);
2269217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    errors |= ERROR_UNRECOGNIZED;
2270217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            }
2271217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2272217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileMain:             // 2-4
2273217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileNbit:             // 2
2274217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileAdvancedRealTime: // 1-4
2275217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileCoreScalable:     // 1-3
2276217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileAdvancedCoding:   // 1-4
2277217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileCore:             // 1-2
2278217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileAdvancedCore:     // 1-4
2279217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileSimpleScalable:   // 0-2
2280217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileHybrid:           // 1-2
22812fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
22822fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // Studio profiles are not supported by our codecs.
22832fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
22842fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // Only profiles that can decode simple object types are considered.
22852fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // The following profiles are not able to.
2286217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileBasicAnimated:    // 1-2
2287217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileScalableTexture:  // 1
2288217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileSimpleFace:       // 1-2
22892fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3
2290217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.MPEG4ProfileSimpleFBA:        // 1-2
2291217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.i(TAG, "Unsupported profile "
2292217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2293217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNSUPPORTED;
2294217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            supported = false;
2295217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2296217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2297217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized profile "
2298217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2299217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2300217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2301217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    if (supported) {
2302217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        errors &= ~ERROR_NONE_SUPPORTED;
2303217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2304217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
2305217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocks = Math.max(FS, maxBlocks);
2306217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBps = Math.max(BR * 1000, maxBps);
23072fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    if (strict) {
23082fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxWidth = Math.max(W, maxWidth);
23092fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxHeight = Math.max(H, maxHeight);
23102fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxRate = Math.max(FR, maxRate);
23112fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    } else {
23122fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // assuming max 60 fps frame rate and 1:2 aspect ratio
23132fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        int maxDim = (int)Math.sqrt(FS * 2);
23142fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxWidth = Math.max(maxDim, maxWidth);
23152fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxHeight = Math.max(maxDim, maxHeight);
23162fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxRate = Math.max(Math.max(FR, 60), maxRate);
23172fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    }
2318981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar                }
2319217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                applyMacroBlockLimits(maxWidth, maxHeight,
2320217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxBlocks, maxBlocksPerSecond,
2321217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        16 /* blockWidth */, 16 /* blockHeight */,
2322217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        1 /* widthAlignment */, 1 /* heightAlignment */);
2323217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
2324217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
2325217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int maxWidth = 11, maxHeight = 9, maxRate = 15;
23262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int minWidth = maxWidth, minHeight = maxHeight;
23272fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                int minAlignment = 16;
2328217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocks = 99;
2329217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocksPerSecond = 1485;
2330217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBps = 64000;
2331217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (CodecProfileLevel profileLevel: profileLevels) {
23322fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0, minW = minWidth, minH = minHeight;
23332fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    boolean strict = false; // true: support only sQCIF, QCIF (maybe CIF)
2334217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.level) {
2335217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level10:
23362fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            strict = true; // only supports sQCIF & QCIF
2337217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 15; W = 11; H =  9; BR =   1; MBPS =  W * H * FR; break;
2338217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level20:
23392fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            strict = true; // only supports sQCIF, QCIF & CIF
23402fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            FR = 30; W = 22; H = 18; BR =   2; MBPS =  W * H * 15; break;
2341217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level30:
23422fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            strict = true; // only supports sQCIF, QCIF & CIF
2343217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 30; W = 22; H = 18; BR =   6; MBPS =  W * H * FR; break;
2344217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level40:
23452fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            strict = true; // only supports sQCIF, QCIF & CIF
2346217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 30; W = 22; H = 18; BR =  32; MBPS =  W * H * FR; break;
2347217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level45:
2348217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            // only implies level 10 support
23492fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            strict = profileLevel.profile == CodecProfileLevel.H263ProfileBaseline
23502fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                    || profileLevel.profile ==
23512fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                            CodecProfileLevel.H263ProfileBackwardCompatible;
23522fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            if (!strict) {
23532fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                                minW = 1; minH = 1; minAlignment = 4;
23542fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            }
23552fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            FR = 15; W = 11; H =  9; BR =   2; MBPS =  W * H * FR; break;
2356217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level50:
2357217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            // only supports 50fps for H > 15
23582fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            minW = 1; minH = 1; minAlignment = 4;
2359217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 60; W = 22; H = 18; BR =  64; MBPS =  W * H * 50; break;
2360217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level60:
2361217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            // only supports 50fps for H > 15
23622fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            minW = 1; minH = 1; minAlignment = 4;
2363217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 60; W = 45; H = 18; BR = 128; MBPS =  W * H * 50; break;
2364217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263Level70:
2365217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            // only supports 50fps for H > 30
23662fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                            minW = 1; minH = 1; minAlignment = 4;
2367217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 60; W = 45; H = 36; BR = 256; MBPS =  W * H * 50; break;
2368217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2369217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile
2370217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + "/" + profileLevel.level + " for " + mime);
2371217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2372217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2373217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.profile) {
2374217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileBackwardCompatible:
2375217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileBaseline:
2376217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileH320Coding:
2377217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileHighCompression:
2378217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileHighLatency:
2379217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileInterlace:
2380217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileInternet:
2381217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileISWV2:
2382217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.H263ProfileISWV3:
2383217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2384217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2385217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized profile "
2386217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2387217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2388217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
23892fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    if (strict) {
23902fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // Strict levels define sub-QCIF min size and enumerated sizes. We cannot
23912fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // express support for "only sQCIF & QCIF (& CIF)" using VideoCapabilities
23922fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // but we can express "only QCIF (& CIF)", so set minimume size at QCIF.
23932fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // minW = 8; minH = 6;
23942fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        minW = 11; minH = 9;
23952fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    } else {
23962fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // any support for non-strict levels (including unrecognized profiles or
23972fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // levels) allow custom frame size support beyond supported limits
23982fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        // (other than bitrate)
23992fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        mAllowMbOverride = true;
24002fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    }
2401217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    errors &= ~ERROR_NONE_SUPPORTED;
2402217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
2403217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocks = Math.max(W * H, maxBlocks);
2404217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBps = Math.max(BR * 64000, maxBps);
2405217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxWidth = Math.max(W, maxWidth);
2406217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxHeight = Math.max(H, maxHeight);
2407217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxRate = Math.max(FR, maxRate);
24082fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    minWidth = Math.min(minW, minWidth);
24092fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    minHeight = Math.min(minH, minHeight);
2410217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
24112fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                // unless we encountered custom frame size support, limit size to QCIF and CIF
24122fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                // using aspect ratio.
24132fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                if (!mAllowMbOverride) {
24142fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    mBlockAspectRatioRange =
24152fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        Range.create(new Rational(11, 9), new Rational(11, 9));
24162fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                }
24172fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                applyMacroBlockLimits(
24182fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        minWidth, minHeight,
24192fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        maxWidth, maxHeight,
2420217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxBlocks, maxBlocksPerSecond,
2421217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        16 /* blockWidth */, 16 /* blockHeight */,
24222fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        minAlignment /* widthAlignment */, minAlignment /* heightAlignment */);
2423217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mFrameRateRange = Range.create(1, maxRate);
2424f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) {
2425f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBlocks = Integer.MAX_VALUE;
2426f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBlocksPerSecond = Integer.MAX_VALUE;
2427217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2428f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                // TODO: set to 100Mbps for now, need a number for VP8
2429217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBps = 100000000;
2430217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2431217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // profile levels are not indicative for VPx, but verify
2432217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // them nonetheless
2433217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (CodecProfileLevel profileLevel: profileLevels) {
2434217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.level) {
2435217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.VP8Level_Version0:
2436217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.VP8Level_Version1:
2437217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.VP8Level_Version2:
2438217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.VP8Level_Version3:
2439217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2440217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2441217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized level "
2442217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.level + " for " + mime);
2443217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2444217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2445217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.profile) {
2446217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.VP8ProfileMain:
2447217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2448217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2449217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized profile "
2450217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2451217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2452217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2453217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    errors &= ~ERROR_NONE_SUPPORTED;
2454981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar                }
2455981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar
2456f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                final int blockSize = 16;
2457217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE,
2458217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxBlocks, maxBlocksPerSecond, blockSize, blockSize,
2459217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        1 /* widthAlignment */, 1 /* heightAlignment */);
2460f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) {
2461f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBlocksPerSecond = 829440;
2462f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBlocks = 36864;
2463f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBps = 200000;
24648acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                int maxDim = 512;
2465f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu
2466f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                for (CodecProfileLevel profileLevel: profileLevels) {
24678acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    long SR = 0; // luma sample rate
24688acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    int FS = 0;  // luma picture size
24698acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    int BR = 0;  // bit rate kbps
24708acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    int D = 0;   // luma dimension
2471f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    switch (profileLevel.level) {
2472f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level1:
24738acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =      829440; FS =    36864; BR =    200; D =   512; break;
2474f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level11:
24758acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =     2764800; FS =    73728; BR =    800; D =   768; break;
2476f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level2:
24778acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =     4608000; FS =   122880; BR =   1800; D =   960; break;
2478f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level21:
24798acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =     9216000; FS =   245760; BR =   3600; D =  1344; break;
2480f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level3:
24818acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =    20736000; FS =   552960; BR =   7200; D =  2048; break;
2482f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level31:
24838acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =    36864000; FS =   983040; BR =  12000; D =  2752; break;
2484f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level4:
24858acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =    83558400; FS =  2228224; BR =  18000; D =  4160; break;
2486f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level41:
24878acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =   160432128; FS =  2228224; BR =  30000; D =  4160; break;
2488f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level5:
24898acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =   311951360; FS =  8912896; BR =  60000; D =  8384; break;
2490f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level51:
24918acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =   588251136; FS =  8912896; BR = 120000; D =  8384; break;
2492f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level52:
24938acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =  1176502272; FS =  8912896; BR = 180000; D =  8384; break;
2494f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level6:
24958acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR =  1176502272; FS = 35651584; BR = 180000; D = 16832; break;
2496f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level61:
24978acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR = 2353004544L; FS = 35651584; BR = 240000; D = 16832; break;
2498f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Level62:
24998acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                            SR = 4706009088L; FS = 35651584; BR = 480000; D = 16832; break;
2500f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        default:
2501f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                            Log.w(TAG, "Unrecognized level "
2502f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                                    + profileLevel.level + " for " + mime);
2503f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                            errors |= ERROR_UNRECOGNIZED;
2504f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    }
2505f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    switch (profileLevel.profile) {
2506f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Profile0:
2507f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Profile1:
2508f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Profile2:
2509f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        case CodecProfileLevel.VP9Profile3:
25102fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        case CodecProfileLevel.VP9Profile2HDR:
25112fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        case CodecProfileLevel.VP9Profile3HDR:
2512f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                            break;
2513f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        default:
2514f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                            Log.w(TAG, "Unrecognized profile "
2515f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                                    + profileLevel.profile + " for " + mime);
2516f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                            errors |= ERROR_UNRECOGNIZED;
2517f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    }
2518f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    errors &= ~ERROR_NONE_SUPPORTED;
2519f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    maxBlocksPerSecond = Math.max(SR, maxBlocksPerSecond);
2520f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    maxBlocks = Math.max(FS, maxBlocks);
2521f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                    maxBps = Math.max(BR * 1000, maxBps);
25228acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                    maxDim = Math.max(D, maxDim);
2523f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                }
2524f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu
2525f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                final int blockSize = 8;
25268acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar                int maxLengthInBlocks = Utils.divUp(maxDim, blockSize);
2527f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBlocks = Utils.divUp(maxBlocks, blockSize * blockSize);
2528f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, blockSize * blockSize);
2529f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu
2530f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                applyMacroBlockLimits(
2531f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        maxLengthInBlocks, maxLengthInBlocks,
2532f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        maxBlocks, maxBlocksPerSecond,
2533f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        blockSize, blockSize,
2534f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu                        1 /* widthAlignment */, 1 /* heightAlignment */);
25355755817422700f6f5e8380921d1f5a728b677dd2Ronghua Wu            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
25362fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                // CTBs are at least 8x8 so use 8x8 block size
25372fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                maxBlocks = 36864 >> 6; // 192x192 pixels == 576 8x8 blocks
2538217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBlocksPerSecond = maxBlocks * 15;
2539217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBps = 128000;
2540217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (CodecProfileLevel profileLevel: profileLevels) {
2541217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    double FR = 0;
2542217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    int FS = 0;
2543217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    int BR = 0;
2544217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.level) {
25452fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                        /* The HEVC spec talks only in a very convoluted manner about the
25462fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                           existence of levels 1-3.1 for High tier, which could also be
25472fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                           understood as 'decoders and encoders should treat these levels
25482fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                           as if they were Main tier', so we do that. */
2549217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel1:
2550217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel1:
2551217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    15; FS =    36864; BR =    128; break;
2552217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel2:
2553217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel2:
2554217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =   122880; BR =   1500; break;
2555217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel21:
2556217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel21:
2557217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =   245760; BR =   3000; break;
2558217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel3:
2559217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel3:
2560217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =   552960; BR =   6000; break;
2561217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel31:
2562217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel31:
2563217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR = 33.75; FS =   983040; BR =  10000; break;
2564217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel4:
2565217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =  2228224; BR =  12000; break;
2566217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel4:
2567217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =  2228224; BR =  30000; break;
2568217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel41:
2569217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    60; FS =  2228224; BR =  20000; break;
2570217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel41:
2571217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    60; FS =  2228224; BR =  50000; break;
2572217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel5:
2573217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =  8912896; BR =  25000; break;
2574217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel5:
2575217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS =  8912896; BR = 100000; break;
2576217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel51:
2577217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    60; FS =  8912896; BR =  40000; break;
2578217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel51:
2579217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    60; FS =  8912896; BR = 160000; break;
2580217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel52:
2581217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =   120; FS =  8912896; BR =  60000; break;
2582217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel52:
2583217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =   120; FS =  8912896; BR = 240000; break;
2584217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel6:
2585217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS = 35651584; BR =  60000; break;
2586217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel6:
2587217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    30; FS = 35651584; BR = 240000; break;
2588217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel61:
2589217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    60; FS = 35651584; BR = 120000; break;
2590217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel61:
2591217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =    60; FS = 35651584; BR = 480000; break;
2592217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCMainTierLevel62:
2593217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =   120; FS = 35651584; BR = 240000; break;
2594217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCHighTierLevel62:
2595217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            FR =   120; FS = 35651584; BR = 800000; break;
2596217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2597217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized level "
2598217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.level + " for " + mime);
2599217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2600217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2601217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    switch (profileLevel.profile) {
2602217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCProfileMain:
2603217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        case CodecProfileLevel.HEVCProfileMain10:
2604f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu                        case CodecProfileLevel.HEVCProfileMain10HDR10:
2605217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            break;
2606217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        default:
2607217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            Log.w(TAG, "Unrecognized profile "
2608217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                                    + profileLevel.profile + " for " + mime);
2609217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            errors |= ERROR_UNRECOGNIZED;
2610217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2611217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2612217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    /* DPB logic:
2613217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    if      (width * height <= FS / 4)    DPB = 16;
2614217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    else if (width * height <= FS / 2)    DPB = 12;
2615217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    else if (width * height <= FS * 0.75) DPB = 8;
2616217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    else                                  DPB = 6;
2617217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    */
2618217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
26192fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar                    FS >>= 6; // convert pixels to blocks
2620217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    errors &= ~ERROR_NONE_SUPPORTED;
2621217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond);
2622217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBlocks = Math.max(FS, maxBlocks);
2623217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    maxBps = Math.max(BR * 1000, maxBps);
2624b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                }
2625b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
2626217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
2627217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                applyMacroBlockLimits(
2628217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxLengthInBlocks, maxLengthInBlocks,
2629217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        maxBlocks, maxBlocksPerSecond,
2630217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        8 /* blockWidth */, 8 /* blockHeight */,
2631217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        1 /* widthAlignment */, 1 /* heightAlignment */);
2632217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else {
2633217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Log.w(TAG, "Unsupported mime " + mime);
2634217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // using minimal bitrate here.  should be overriden by
2635217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // info from media_codecs.xml
2636217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                maxBps = 64000;
2637217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                errors |= ERROR_UNSUPPORTED;
2638217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2639217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBitrateRange = Range.create(1, maxBps);
2640217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mParent.mError |= errors;
2641217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2642217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    }
2643217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2644217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    /**
2645217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar     * A class that supports querying the encoding capabilities of a codec.
2646217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar     */
2647217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar    public static final class EncoderCapabilities {
2648217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
2649217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the supported range of quality values.
2650217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         *
265188833299364b924205b7d99932d192473a82df16Chong Zhang         * Quality is implementation-specific. As a general rule, a higher quality
265288833299364b924205b7d99932d192473a82df16Chong Zhang         * setting results in a better image quality and a lower compression ratio.
2653217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
2654217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getQualityRange() {
2655217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mQualityRange;
2656217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2657217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2658217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /**
2659217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Returns the supported range of encoder complexity values.
2660217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * <p>
2661217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Some codecs may support multiple complexity levels, where higher
2662217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * complexity values use more encoder tools (e.g. perform more
2663217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * intensive calculations) to improve the quality or the compression
2664217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * ratio.  Use a lower value to save power and/or time.
2665217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         */
2666217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public Range<Integer> getComplexityRange() {
2667217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return mComplexityRange;
2668217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2669217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2670217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** Constant quality mode */
2671217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public static final int BITRATE_MODE_CQ = 0;
2672217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** Variable bitrate mode */
2673217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public static final int BITRATE_MODE_VBR = 1;
2674217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** Constant bitrate mode */
2675217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public static final int BITRATE_MODE_CBR = 2;
2676217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2677217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private static final Feature[] bitrates = new Feature[] {
2678217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            new Feature("VBR", BITRATE_MODE_VBR, true),
2679217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            new Feature("CBR", BITRATE_MODE_CBR, false),
2680217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            new Feature("CQ",  BITRATE_MODE_CQ,  false)
2681b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        };
2682b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
2683217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private static int parseBitrateMode(String mode) {
2684217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            for (Feature feat: bitrates) {
2685217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (feat.mName.equalsIgnoreCase(mode)) {
2686217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    return feat.mValue;
2687217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2688217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2689217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return 0;
2690b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
2691b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
2692b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /**
2693217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar         * Query whether a bitrate mode is supported.
2694b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar         */
2695217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean isBitrateModeSupported(int mode) {
2696217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            for (Feature feat: bitrates) {
2697217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (mode == feat.mValue) {
2698217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    return (mBitControl & (1 << mode)) != 0;
2699217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2700217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2701217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return false;
2702b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
2703b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
2704217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mQualityRange;
2705217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Range<Integer> mComplexityRange;
2706217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private CodecCapabilities mParent;
2707217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2708217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /* no public constructor */
2709217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private EncoderCapabilities() { }
2710217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2711b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        /** @hide */
2712217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public static EncoderCapabilities create(
2713217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                MediaFormat info, CodecCapabilities parent) {
2714217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            EncoderCapabilities caps = new EncoderCapabilities();
2715217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            caps.init(info, parent);
2716217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return caps;
2717217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2718217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2719a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang        private void init(MediaFormat info, CodecCapabilities parent) {
2720217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // no support for complexity or quality yet
2721217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mParent = parent;
2722217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mComplexityRange = Range.create(0, 0);
2723217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mQualityRange = Range.create(0, 0);
2724217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mBitControl = (1 << BITRATE_MODE_VBR);
2725217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2726217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            applyLevelLimits();
2727217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            parseFromInfo(info);
2728217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2729217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2730217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void applyLevelLimits() {
2731217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            String mime = mParent.getMimeType();
2732217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) {
2733217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mComplexityRange = Range.create(0, 8);
2734217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mBitControl = (1 << BITRATE_MODE_CQ);
2735217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)
2736217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)
2737217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW)
2738217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)
2739217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) {
2740217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mBitControl = (1 << BITRATE_MODE_CBR);
2741217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2742217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2743217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2744217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private int mBitControl;
2745217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Integer mDefaultComplexity;
2746217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private Integer mDefaultQuality;
2747217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private String mQualityScale;
2748217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2749217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private void parseFromInfo(MediaFormat info) {
2750217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Map<String, Object> map = info.getMap();
2751217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2752217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (info.containsKey("complexity-range")) {
2753217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mComplexityRange = Utils
2754217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        .parseIntRange(info.getString("complexity-range"), mComplexityRange);
2755217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                // TODO should we limit this to level limits?
2756217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2757217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (info.containsKey("quality-range")) {
2758217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mQualityRange = Utils
2759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        .parseIntRange(info.getString("quality-range"), mQualityRange);
2760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2761add5a5a2f887d65cd4f037300e90d986c266f8b3Pawin Vongmasa            if (info.containsKey("feature-bitrate-modes")) {
2762add5a5a2f887d65cd4f037300e90d986c266f8b3Pawin Vongmasa                for (String mode: info.getString("feature-bitrate-modes").split(",")) {
276388833299364b924205b7d99932d192473a82df16Chong Zhang                    mBitControl |= (1 << parseBitrateMode(mode));
2764217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            try {
2768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mDefaultComplexity = Integer.parseInt((String)map.get("complexity-default"));
2769217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } catch (NumberFormatException e) { }
2770217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2771217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            try {
2772217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                mDefaultQuality = Integer.parseInt((String)map.get("quality-default"));
2773217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            } catch (NumberFormatException e) { }
2774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2775217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            mQualityScale = (String)map.get("quality-scale");
2776217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2777217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2778217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        private boolean supports(
2779217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Integer complexity, Integer quality, Integer profile) {
2780217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            boolean ok = true;
2781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && complexity != null) {
2782217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = mComplexityRange.contains(complexity);
2783217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2784217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && quality != null) {
2785217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = mQualityRange.contains(quality);
2786217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2787217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (ok && profile != null) {
2788217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                for (CodecProfileLevel pl: mParent.profileLevels) {
2789217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    if (pl.profile == profile) {
2790217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        profile = null;
2791217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                        break;
2792217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    }
2793217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2794217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                ok = profile == null;
2795217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2796217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return ok;
2797217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2798217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2799217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
2800a0b72a6cdd6e575e2ea0ec2bffc9a361c4041665Chong Zhang        public void getDefaultFormat(MediaFormat format) {
2801217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // don't list trivial quality/complexity as default for now
2802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (!mQualityRange.getUpper().equals(mQualityRange.getLower())
2803217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    && mDefaultQuality != null) {
2804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                format.setInteger(MediaFormat.KEY_QUALITY, mDefaultQuality);
2805217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2806217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (!mComplexityRange.getUpper().equals(mComplexityRange.getLower())
2807217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    && mDefaultComplexity != null) {
2808217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                format.setInteger(MediaFormat.KEY_COMPLEXITY, mDefaultComplexity);
2809217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2810217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // bitrates are listed in order of preference
2811217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            for (Feature feat: bitrates) {
2812217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if ((mBitControl & (1 << feat.mValue)) != 0) {
2813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    format.setInteger(MediaFormat.KEY_BITRATE_MODE, feat.mValue);
2814217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    break;
2815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2817217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        }
2818217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2819217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        /** @hide */
2820217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar        public boolean supportsFormat(MediaFormat format) {
2821217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final Map<String, Object> map = format.getMap();
2822217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            final String mime = mParent.getMimeType();
2823217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2824217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer mode = (Integer)map.get(MediaFormat.KEY_BITRATE_MODE);
2825217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (mode != null && !isBitrateModeSupported(mode)) {
2826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                return false;
2827217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2828217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2829217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer complexity = (Integer)map.get(MediaFormat.KEY_COMPLEXITY);
2830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (MediaFormat.MIMETYPE_AUDIO_FLAC.equalsIgnoreCase(mime)) {
2831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Integer flacComplexity =
2832217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL);
2833217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (complexity == null) {
2834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    complexity = flacComplexity;
28355c5978985a3457539d1f3b611f23d26b77484536Andreas Gampe                } else if (flacComplexity != null && !complexity.equals(flacComplexity)) {
2836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    throw new IllegalArgumentException(
2837217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            "conflicting values for complexity and " +
2838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            "flac-compression-level");
2839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2842217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            // other audio parameters
2843217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
2844217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mime)) {
2845217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE);
2846217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                if (profile == null) {
2847217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    profile = aacProfile;
28485c5978985a3457539d1f3b611f23d26b77484536Andreas Gampe                } else if (aacProfile != null && !aacProfile.equals(profile)) {
2849217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                    throw new IllegalArgumentException(
2850217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                            "conflicting values for profile and aac-profile");
2851217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar                }
2852217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            }
2853217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2854217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            Integer quality = (Integer)map.get(MediaFormat.KEY_QUALITY);
2855217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar
2856217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar            return supports(complexity, quality, profile);
2857b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
285860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    };
285960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
2860c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main    /**
2861c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * Encapsulates the profiles available for a codec component.
2862c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * <p>You can get a set of {@link MediaCodecInfo.CodecProfileLevel} objects for a given
2863c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * {@link MediaCodecInfo} object from the
2864c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * {@link MediaCodecInfo.CodecCapabilities#profileLevels} field.
2865c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     */
286660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    public static final class CodecProfileLevel {
286760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_VIDEO_AVCPROFILETYPE
286860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileBaseline = 0x01;
286960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileMain     = 0x02;
287060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileExtended = 0x04;
287160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileHigh     = 0x08;
287260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileHigh10   = 0x10;
287360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileHigh422  = 0x20;
287460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCProfileHigh444  = 0x40;
28759da5f1ba583d8e42b6690ddf414298a947c8f07fLajos Molnar        public static final int AVCProfileConstrainedBaseline = 0x10000;
28769da5f1ba583d8e42b6690ddf414298a947c8f07fLajos Molnar        public static final int AVCProfileConstrainedHigh     = 0x80000;
287760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
287860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_VIDEO_AVCLEVELTYPE
287960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel1       = 0x01;
288060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel1b      = 0x02;
288160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel11      = 0x04;
288260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel12      = 0x08;
288360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel13      = 0x10;
288460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel2       = 0x20;
288560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel21      = 0x40;
288660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel22      = 0x80;
288760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel3       = 0x100;
288860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel31      = 0x200;
288960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel32      = 0x400;
289060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel4       = 0x800;
289160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel41      = 0x1000;
289260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel42      = 0x2000;
289360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel5       = 0x4000;
289460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AVCLevel51      = 0x8000;
2895b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        public static final int AVCLevel52      = 0x10000;
289660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
289760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_VIDEO_H263PROFILETYPE
289860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileBaseline             = 0x01;
289960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileH320Coding           = 0x02;
290060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileBackwardCompatible   = 0x04;
290160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileISWV2                = 0x08;
290260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileISWV3                = 0x10;
290360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileHighCompression      = 0x20;
290460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileInternet             = 0x40;
290560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileInterlace            = 0x80;
290660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263ProfileHighLatency          = 0x100;
290760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
290860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_VIDEO_H263LEVELTYPE
290960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level10      = 0x01;
291060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level20      = 0x02;
291160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level30      = 0x04;
291260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level40      = 0x08;
291360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level45      = 0x10;
291460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level50      = 0x20;
291560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level60      = 0x40;
291660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int H263Level70      = 0x80;
291760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
291860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_VIDEO_MPEG4PROFILETYPE
291960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileSimple              = 0x01;
292060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileSimpleScalable      = 0x02;
292160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileCore                = 0x04;
292260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileMain                = 0x08;
292360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileNbit                = 0x10;
292460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileScalableTexture     = 0x20;
292560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileSimpleFace          = 0x40;
292660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileSimpleFBA           = 0x80;
292760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileBasicAnimated       = 0x100;
292860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileHybrid              = 0x200;
292960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileAdvancedRealTime    = 0x400;
293060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileCoreScalable        = 0x800;
293160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileAdvancedCoding      = 0x1000;
293260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileAdvancedCore        = 0x2000;
293360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileAdvancedScalable    = 0x4000;
293460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4ProfileAdvancedSimple      = 0x8000;
293560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
293660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_VIDEO_MPEG4LEVELTYPE
293760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level0      = 0x01;
293860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level0b     = 0x02;
293960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level1      = 0x04;
294060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level2      = 0x08;
294160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level3      = 0x10;
29422a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar        public static final int MPEG4Level3b     = 0x18;
294360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level4      = 0x20;
294460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level4a     = 0x40;
294560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int MPEG4Level5      = 0x80;
29462a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar        public static final int MPEG4Level6      = 0x100;
294760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
294834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        // from OMX_VIDEO_MPEG2PROFILETYPE
294934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2ProfileSimple              = 0x00;
295034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2ProfileMain                = 0x01;
295134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2Profile422                 = 0x02;
295234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2ProfileSNR                 = 0x03;
295334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2ProfileSpatial             = 0x04;
295434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2ProfileHigh                = 0x05;
295534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar
295634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        // from OMX_VIDEO_MPEG2LEVELTYPE
295734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2LevelLL     = 0x00;
295834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2LevelML     = 0x01;
295934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2LevelH14    = 0x02;
296034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar        public static final int MPEG2LevelHL     = 0x03;
29612a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar        public static final int MPEG2LevelHP     = 0x04;
296234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar
296360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        // from OMX_AUDIO_AACPROFILETYPE
296460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectMain       = 1;
296560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectLC         = 2;
296660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectSSR        = 3;
296760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectLTP        = 4;
296860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectHE         = 5;
296960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectScalable   = 6;
297060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectERLC       = 17;
29717c1cb0d5a5420823e63d59daf140844921407e29Jean-Michel Trivi        public static final int AACObjectERScalable = 20;
297260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectLD         = 23;
297360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectHE_PS      = 29;
297460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public static final int AACObjectELD        = 39;
29759a30362790d9975d0bb29c30af8a9bfb2226f172Jean-Michel Trivi        /** xHE-AAC (includes USAC) */
29769a30362790d9975d0bb29c30af8a9bfb2226f172Jean-Michel Trivi        public static final int AACObjectXHE        = 42;
297760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
2978e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        // from OMX_VIDEO_VP8LEVELTYPE
2979e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        public static final int VP8Level_Version0 = 0x01;
2980e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        public static final int VP8Level_Version1 = 0x02;
2981e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        public static final int VP8Level_Version2 = 0x04;
2982e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        public static final int VP8Level_Version3 = 0x08;
2983e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin
2984e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        // from OMX_VIDEO_VP8PROFILETYPE
2985e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin        public static final int VP8ProfileMain = 0x01;
2986e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin
2987f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu        // from OMX_VIDEO_VP9PROFILETYPE
2988f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        public static final int VP9Profile0 = 0x01;
2989f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        public static final int VP9Profile1 = 0x02;
2990f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        public static final int VP9Profile2 = 0x04;
2991f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        public static final int VP9Profile3 = 0x08;
2992f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        // HDR profiles also support passing HDR metadata
2993f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        public static final int VP9Profile2HDR = 0x1000;
2994f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang        public static final int VP9Profile3HDR = 0x2000;
2995f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu
2996f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu        // from OMX_VIDEO_VP9LEVELTYPE
29979186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level1  = 0x1;
29989186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level11 = 0x2;
29999186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level2  = 0x4;
30009186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level21 = 0x8;
30019186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level3  = 0x10;
30029186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level31 = 0x20;
30039186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level4  = 0x40;
30049186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level41 = 0x80;
30059186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level5  = 0x100;
30069186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level51 = 0x200;
30079186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level52 = 0x400;
30089186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level6  = 0x800;
30099186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level61 = 0x1000;
30109186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang        public static final int VP9Level62 = 0x2000;
3011f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu
3012aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        // from OMX_VIDEO_HEVCPROFILETYPE
3013f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu        public static final int HEVCProfileMain        = 0x01;
3014f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu        public static final int HEVCProfileMain10      = 0x02;
3015e536bf7b22b35ddebb58d2451533b75d825113e7Chong Zhang        public static final int HEVCProfileMainStill   = 0x04;
3016f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu        public static final int HEVCProfileMain10HDR10 = 0x1000;
3017aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad
3018aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        // from OMX_VIDEO_HEVCLEVELTYPE
3019aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel1  = 0x1;
3020aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel1  = 0x2;
3021aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel2  = 0x4;
3022aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel2  = 0x8;
3023aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel21 = 0x10;
3024aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel21 = 0x20;
3025aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel3  = 0x40;
3026aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel3  = 0x80;
3027aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel31 = 0x100;
3028aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel31 = 0x200;
3029aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel4  = 0x400;
3030aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel4  = 0x800;
3031aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel41 = 0x1000;
3032aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel41 = 0x2000;
3033aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel5  = 0x4000;
3034aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel5  = 0x8000;
3035aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel51 = 0x10000;
3036aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel51 = 0x20000;
3037aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel52 = 0x40000;
3038aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel52 = 0x80000;
3039aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel6  = 0x100000;
3040aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel6  = 0x200000;
3041aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel61 = 0x400000;
3042aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel61 = 0x800000;
3043aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCMainTierLevel62 = 0x1000000;
3044aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad        public static final int HEVCHighTierLevel62 = 0x2000000;
3045e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin
30462fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar        private static final int HEVCHighTierLevels =
30472fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar            HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 |
30482fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar            HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 |
30492fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar            HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 |
30502fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar            HEVCHighTierLevel62;
30512fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar
3052d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        // from OMX_VIDEO_DOLBYVISIONPROFILETYPE
305332e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvavPer = 0x1;
305432e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvavPen = 0x2;
305532e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvheDer = 0x4;
305632e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvheDen = 0x8;
305732e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvheDtr = 0x10;
305832e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvheStn = 0x20;
305932e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu        public static final int DolbyVisionProfileDvheDth = 0x40;
3060f939e4adf1b3c6f9d7d26def48503654801f700dHangyu Kuang        public static final int DolbyVisionProfileDvheDtb = 0x80;
3061307da62b1cf8040cba9d9c74c2d5795e6afcd950Previr Rangroo        public static final int DolbyVisionProfileDvheSt = 0x100;
3062307da62b1cf8040cba9d9c74c2d5795e6afcd950Previr Rangroo        public static final int DolbyVisionProfileDvavSe = 0x200;
3063d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu
3064d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        // from OMX_VIDEO_DOLBYVISIONLEVELTYPE
3065d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelHd24    = 0x1;
3066d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelHd30    = 0x2;
3067d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelFhd24   = 0x4;
3068d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelFhd30   = 0x8;
3069d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelFhd60   = 0x10;
3070d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelUhd24   = 0x20;
3071d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelUhd30   = 0x40;
3072d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelUhd48   = 0x80;
3073d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu        public static final int DolbyVisionLevelUhd60   = 0x100;
3074d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu
307560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        /**
307660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         * Defined in the OpenMAX IL specs, depending on the type of media
307760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         * this can be OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE,
3078f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu         * OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_VP8PROFILETYPE or OMX_VIDEO_VP9PROFILETYPE.
307960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         */
308060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public int profile;
308160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
308260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        /**
308360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         * Defined in the OpenMAX IL specs, depending on the type of media
308460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         * this can be OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE
3085f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu         * OMX_VIDEO_MPEG4LEVELTYPE, OMX_VIDEO_VP8LEVELTYPE or OMX_VIDEO_VP9LEVELTYPE.
3086f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu         *
3087f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu         * Note that VP9 decoder on platforms before {@link android.os.Build.VERSION_CODES#N} may
3088f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu         * not advertise a profile level support. For those VP9 decoders, please use
3089f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu         * {@link VideoCapabilities} to determine the codec capabilities.
309060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber         */
309160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber        public int level;
309262b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim
309362b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim        @Override
309462b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim        public boolean equals(Object obj) {
309562b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim            if (obj == null) {
309662b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim                return false;
309762b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim            }
309862b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim            if (obj instanceof CodecProfileLevel) {
309962b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim                CodecProfileLevel other = (CodecProfileLevel)obj;
310062b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim                return other.profile == profile && other.level == level;
310162b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim            }
310262b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim            return false;
310362b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim        }
310462b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim
310562b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim        @Override
310662b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim        public int hashCode() {
310762b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim            return Long.hashCode(((long)profile << Integer.SIZE) | level);
310862b01c7d26d6fc1d523f96dfd883ddffcd929d58Wonsik Kim        }
310960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    };
311060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber
3111ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber    /**
3112ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber     * Enumerates the capabilities of the codec component. Since a single
3113ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber     * component can support data of a variety of types, the type has to be
3114ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber     * specified to yield a meaningful result.
3115c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main     * @param type The MIME type to query
3116ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber     */
311760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    public final CodecCapabilities getCapabilitiesForType(
311860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber            String type) {
3119b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        CodecCapabilities caps = mCaps.get(type);
3120b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        if (caps == null) {
3121b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            throw new IllegalArgumentException("codec does not support type");
3122b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
3123b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        // clone writable object
3124b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        return caps.dup();
3125b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    }
3126b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
3127b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    /** @hide */
3128b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar    public MediaCodecInfo makeRegular() {
3129b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        ArrayList<CodecCapabilities> caps = new ArrayList<CodecCapabilities>();
3130b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        for (CodecCapabilities c: mCaps.values()) {
3131b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            if (c.isRegular()) {
3132b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                caps.add(c);
3133b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            }
3134b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
3135b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        if (caps.size() == 0) {
3136b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return null;
3137b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        } else if (caps.size() == mCaps.size()) {
3138b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar            return this;
3139b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        }
3140b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar
3141b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar        return new MediaCodecInfo(
3142b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                mName, mIsEncoder,
3143b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar                caps.toArray(new CodecCapabilities[caps.size()]));
314460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber    }
314560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber}
3146