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 < 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 < 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