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 19b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Log; 20b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Pair; 21b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Range; 22b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Rational; 23b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Size; 24b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 25b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.ArrayList; 26b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Arrays; 27b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Comparator; 28b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.HashMap; 29b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Map; 30b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Set; 31b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 32b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static android.media.Utils.intersectSortedDistinctRanges; 33b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static android.media.Utils.sortDistinctRanges; 34b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static com.android.internal.util.Preconditions.checkArgumentPositive; 35b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static com.android.internal.util.Preconditions.checkNotNull; 36b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 37c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main/** 38c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Provides information about a given media codec available on the device. You can 39c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * iterate through all codecs available by querying {@link MediaCodecList}. For example, 40c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * here's how to find an encoder that supports a given MIME type: 41c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <pre> 42c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * private static MediaCodecInfo selectCodec(String mimeType) { 43c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * int numCodecs = MediaCodecList.getCodecCount(); 44c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * for (int i = 0; i < numCodecs; i++) { 45c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); 46c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * 47c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * if (!codecInfo.isEncoder()) { 48c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * continue; 49c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 50c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * 51c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * String[] types = codecInfo.getSupportedTypes(); 52c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * for (int j = 0; j < types.length; j++) { 53c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * if (types[j].equalsIgnoreCase(mimeType)) { 54c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * return codecInfo; 55c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 56c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 57c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 58c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * return null; 59c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * }</pre> 60c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * 61c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main */ 6260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberpublic final class MediaCodecInfo { 63b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean mIsEncoder; 64b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private String mName; 65b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private Map<String, CodecCapabilities> mCaps; 6660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 67b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /* package private */ MediaCodecInfo( 68b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String name, boolean isEncoder, CodecCapabilities[] caps) { 69b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mName = name; 70b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mIsEncoder = isEncoder; 71b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mCaps = new HashMap<String, CodecCapabilities>(); 72b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (CodecCapabilities c: caps) { 73217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mCaps.put(c.getMimeType(), c); 74b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 7560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 7660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 7760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 7860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Retrieve the codec name. 7960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 8060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final String getName() { 81b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mName; 8260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 8360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 8460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 8560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Query if the codec is an encoder. 8660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 8760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final boolean isEncoder() { 88b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mIsEncoder; 8960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 9060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 9160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 9260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Query the media types supported by the codec. 9360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 9460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final String[] getSupportedTypes() { 95b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Set<String> typeSet = mCaps.keySet(); 96b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String[] types = typeSet.toArray(new String[typeSet.size()]); 97b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Arrays.sort(types); 98b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return types; 9960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 10060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static int checkPowerOfTwo(int value, String message) { 102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if ((value & (value - 1)) != 0) { 103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException(message); 104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return value; 106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static class Feature { 109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public String mName; 110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int mValue; 111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean mDefault; 112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Feature(String name, int value, boolean def) { 113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mName = name; 114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mValue = value; 115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefault = def; 116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 118217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // COMMON CONSTANTS 120217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Integer> POSITIVE_INTEGERS = 121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(1, Integer.MAX_VALUE); 122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Long> POSITIVE_LONGS = 123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(1l, Long.MAX_VALUE); 124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Rational> POSITIVE_RATIONALS = 125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(new Rational(1, Integer.MAX_VALUE), 126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(Integer.MAX_VALUE, 1)); 127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768); 128217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960); 129216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000); 130217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // found stuff that is not supported by framework (=> this should not happen) 132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int ERROR_UNRECOGNIZED = (1 << 0); 133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // found profile/level for which we don't have capability estimates 134217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int ERROR_UNSUPPORTED = (1 << 1); 135217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // have not found any profile/level for which we don't have capability estimate 136217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int ERROR_NONE_SUPPORTED = (1 << 2); 137217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 139ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber /** 140c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Encapsulates the capabilities of a given codec component. 141c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * For example, what profile/level combinations it supports and what colorspaces 14280c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * it is capable of providing the decoded data in, as well as some 14380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * codec-type specific capability flags. 144c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <p>You can get an instance for a given {@link MediaCodecInfo} object with 145c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * {@link MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType()}, passing a MIME type. 146ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber */ 14760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final class CodecCapabilities { 148b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public CodecCapabilities() { 149b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 150b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 151b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // CLASSIFICATION 152b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private String mMime; 153b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 154b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // LEGACY FIELDS 155b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 156ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // Enumerates supported profile/level combinations as defined 157ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // by the type of encoded data. These combinations impose restrictions 158ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // on video resolution, bitrate... and limit the available encoder tools 159ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // such as B-frame support, arithmetic coding... 160b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public CodecProfileLevel[] profileLevels; // NOTE this array is modifiable by user 16160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 16260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_COLOR_FORMATTYPE 163b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatMonochrome = 1; 164b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format8bitRGB332 = 2; 165b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format12bitRGB444 = 3; 166b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitARGB4444 = 4; 167b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitARGB1555 = 5; 168b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitRGB565 = 6; 169b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitBGR565 = 7; 170b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format18bitRGB666 = 8; 171b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format18bitARGB1665 = 9; 172b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format19bitARGB1666 = 10; 173b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24bitRGB888 = 11; 174b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24bitBGR888 = 12; 175b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24bitARGB1887 = 13; 176b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format25bitARGB1888 = 14; 177b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format32bitBGRA8888 = 15; 178b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format32bitARGB8888 = 16; 179b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV411Planar = 17; 180b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV411PackedPlanar = 18; 181b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420Planar = 19; 182b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420PackedPlanar = 20; 183b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420SemiPlanar = 21; 184b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422Planar = 22; 185b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422PackedPlanar = 23; 186b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422SemiPlanar = 24; 187b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYCbYCr = 25; 188b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYCrYCb = 26; 189b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatCbYCrY = 27; 190b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatCrYCbY = 28; 191b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV444Interleaved = 29; 192b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatRawBayer8bit = 30; 193b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatRawBayer10bit = 31; 194b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatRawBayer8bitcompressed = 32; 195b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL2 = 33; 196b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL4 = 34; 197b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL8 = 35; 198b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL16 = 36; 199b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL24 = 37; 200b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL32 = 38; 201b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420PackedSemiPlanar = 39; 202b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422PackedSemiPlanar = 40; 203b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format18BitBGR666 = 41; 204b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24BitARGB6666 = 42; 205b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24BitABGR6666 = 43; 206b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 207b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100; 20834f17dd1f615c6285f4f344eb700923e2432e48eAndy McFadden // COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference. 20934f17dd1f615c6285f4f344eb700923e2432e48eAndy McFadden // In OMX this is called OMX_COLOR_FormatAndroidOpaque. 210b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatSurface = 0x7F000789; 211b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // This corresponds to YUV_420_888 format 212b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420Flexible = 0x7F420888; 213b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00; 21460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 21560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 21660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Defined in the OpenMAX IL specs, color format values are drawn from 21760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * OMX_COLOR_FORMATTYPE. 21860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 219b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public int[] colorFormats; // NOTE this array is modifiable by user 22080c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar 221b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // FEATURES 222b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 223b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private int mFlagsSupported; 224b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private int mFlagsRequired; 225b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private int mFlagsVerified; 22680c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar 22780c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar /** 22880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * <b>video decoder only</b>: codec supports seamless resolution changes. 22980c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar */ 230b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final String FEATURE_AdaptivePlayback = "adaptive-playback"; 231b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 232b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 233b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <b>video decoder only</b>: codec supports secure decryption. 234b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 235b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final String FEATURE_SecurePlayback = "secure-playback"; 236b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 237b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 238b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <b>video or audio decoder only</b>: codec supports tunneled playback. 239b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 240b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final String FEATURE_TunneledPlayback = "tunneled-playback"; 24180c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar 24280c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar /** 24380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * Query codec feature capabilities. 244b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <p> 245b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * These features are supported to be used by the codec. These 246b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * include optional features that can be turned on, as well as 247b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * features that are always on. 24880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar */ 24980c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar public final boolean isFeatureSupported(String name) { 250b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return checkFeature(name, mFlagsSupported); 251b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 252b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 253b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 254b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Query codec feature requirements. 255b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <p> 256b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * These features are required to be used by the codec, and as such, 257b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * they are always turned on. 258b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 259b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public final boolean isFeatureRequired(String name) { 260b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return checkFeature(name, mFlagsRequired); 261b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 262b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 263b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private static final Feature[] decoderFeatures = { 264b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new Feature(FEATURE_AdaptivePlayback, (1 << 0), true), 265b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new Feature(FEATURE_SecurePlayback, (1 << 1), false), 266b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new Feature(FEATURE_TunneledPlayback, (1 << 2), false), 267b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar }; 268b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 269b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 270b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public String[] validFeatures() { 271b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Feature[] features = getValidFeatures(); 272b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String[] res = new String[features.length]; 273b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (int i = 0; i < res.length; i++) { 274b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar res[i] = features[i].mName; 275b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 276b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return res; 277b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 278b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 279b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private Feature[] getValidFeatures() { 280b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (!isEncoder()) { 281b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return decoderFeatures; 282b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 283b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return new Feature[] {}; 284b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 285b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 286b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean checkFeature(String name, int flags) { 287b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 288b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (feat.mName.equals(name)) { 289b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return (flags & feat.mValue) != 0; 290b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 29180c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar } 29280c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar return false; 29380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar } 294b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 295b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 296b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public boolean isRegular() { 297b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // regular codecs only require default features 298b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 299b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (!feat.mDefault && isFeatureRequired(feat.mName)) { 300b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 301b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 302b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 303b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return true; 304b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 305b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 306b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 307b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Query whether codec supports a given {@link MediaFormat}. 308b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * @param format media format with optional feature directives. 309b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * @throws IllegalArgumentException if format is not a valid media format. 310b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * @return whether the codec capabilities support the given format 311b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * and feature requests. 312b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 313b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public final boolean isFormatSupported(MediaFormat format) { 314b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar final Map<String, Object> map = format.getMap(); 315b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar final String mime = (String)map.get(MediaFormat.KEY_MIME); 316b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 317b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // mime must match if present 318b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mime != null && !mMime.equalsIgnoreCase(mime)) { 319b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 320b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 321b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 322b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // check feature support 323b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 324b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Integer yesNo = (Integer)map.get(MediaFormat.KEY_FEATURE_ + feat.mName); 325dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar if (yesNo == null) { 326dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar continue; 327dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar } 328b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if ((yesNo == 1 && !isFeatureSupported(feat.mName)) || 329b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar (yesNo == 0 && isFeatureRequired(feat.mName))) { 330b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 331b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 332b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 333b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) { 334b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 335b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 336b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mVideoCaps != null && !mVideoCaps.supportsFormat(format)) { 337b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 338b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 339b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mEncoderCaps != null && !mEncoderCaps.supportsFormat(format)) { 340b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 341b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 342b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return true; 343b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 344b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 345217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // errors while reading profile levels - accessed from sister capabilities 346217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int mError; 347b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 348b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private static final String TAG = "CodecCapabilities"; 349b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 350b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // NEW-STYLE CAPABILITIES 351217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private AudioCapabilities mAudioCaps; 352217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private VideoCapabilities mVideoCaps; 353217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private EncoderCapabilities mEncoderCaps; 354217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private MediaFormat mDefaultFormat; 355b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 356b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 357b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Returns a MediaFormat object with default values for configurations that have 358b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * defaults. 359b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 360217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public MediaFormat getDefaultFormat() { 361b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mDefaultFormat; 362b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 363b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 364b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 365b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Returns the mime type for which this codec-capability object was created. 366b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 367217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public String getMimeType() { 368b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mMime; 369b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 370b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 371217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean isAudio() { 372217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mAudioCaps != null; 373217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 374217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 375b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 376217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the audio capabilities or {@code null} if this is not an audio codec. 377b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 378217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public AudioCapabilities getAudioCapabilities() { 379217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mAudioCaps; 380b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 381b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 382b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean isEncoder() { 383b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mEncoderCaps != null; 384b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 385b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 386b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 387217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the encoding capabilities or {@code null} if this is not an encoder. 388b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 389217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public EncoderCapabilities getEncoderCapabilities() { 390217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mEncoderCaps; 391b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 392b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 393b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean isVideo() { 394b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mVideoCaps != null; 395b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 396b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 397b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 398b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Returns the video capabilities or {@code null} if this is not a video codec. 399b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 400217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public VideoCapabilities getVideoCapabilities() { 401b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mVideoCaps; 402b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 403b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 404217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 405217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public CodecCapabilities dup() { 406217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return new CodecCapabilities( 407217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // clone writable arrays 408217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Arrays.copyOf(profileLevels, profileLevels.length), 409217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Arrays.copyOf(colorFormats, colorFormats.length), 410217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar isEncoder(), 411217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFlagsVerified, 412217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefaultFormat, 413217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mCapabilitiesInfo); 414217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 415217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 416b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 417b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Retrieve the codec capabilities for a certain {@code mime type}, {@code 418b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * profile} and {@code level}. If the type, or profile-level combination 419b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * is not understood by the framework, it returns null. 420b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 421a18b69f5907ef27b9954dfcbe8f60d29fcec2be7Lajos Molnar public static CodecCapabilities createFromProfileLevel( 422b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String mime, int profile, int level) { 423b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecProfileLevel pl = new CodecProfileLevel(); 424b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar pl.profile = profile; 425b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar pl.level = level; 426b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar MediaFormat defaultFormat = new MediaFormat(); 427b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar defaultFormat.setString(MediaFormat.KEY_MIME, mime); 428b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 429b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecCapabilities ret = new CodecCapabilities( 430b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new CodecProfileLevel[] { pl }, new int[0], true /* encoder */, 431b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 0 /* flags */, defaultFormat, new MediaFormat() /* info */); 432b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (ret.mError != 0) { 433b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return null; 434b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 435b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return ret; 436b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 437b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 438b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /* package private */ CodecCapabilities( 439b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecProfileLevel[] profLevs, int[] colFmts, 440b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar boolean encoder, int flags, 441b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Map<String, Object>defaultFormatMap, 442b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Map<String, Object>capabilitiesMap) { 443b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar this(profLevs, colFmts, encoder, flags, 444b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new MediaFormat(defaultFormatMap), 445b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new MediaFormat(capabilitiesMap)); 446b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 447b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 448b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private MediaFormat mCapabilitiesInfo; 449b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 450b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /* package private */ CodecCapabilities( 451b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecProfileLevel[] profLevs, int[] colFmts, boolean encoder, int flags, 452b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar MediaFormat defaultFormat, MediaFormat info) { 453b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar final Map<String, Object> map = info.getMap(); 454b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar profileLevels = profLevs; 455b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar colorFormats = colFmts; 456b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mFlagsVerified = flags; 457b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mDefaultFormat = defaultFormat; 458b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mCapabilitiesInfo = info; 459b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mMime = mDefaultFormat.getString(MediaFormat.KEY_MIME); 460b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 461b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mMime.toLowerCase().startsWith("audio/")) { 462b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mAudioCaps = AudioCapabilities.create(info, this); 463981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar mAudioCaps.setDefaultFormat(mDefaultFormat); 464b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } else if (mMime.toLowerCase().startsWith("video/")) { 465b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mVideoCaps = VideoCapabilities.create(info, this); 466b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 467b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (encoder) { 468b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mEncoderCaps = EncoderCapabilities.create(info, this); 469981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar mEncoderCaps.setDefaultFormat(mDefaultFormat); 470b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 471b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 472b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 473981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar String key = MediaFormat.KEY_FEATURE_ + feat.mName; 474981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar Integer yesNo = (Integer)map.get(key); 475b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (yesNo == null) { 476b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar continue; 477dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar } 478dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar if (yesNo > 0) { 479b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mFlagsRequired |= feat.mValue; 480b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 481dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar mFlagsSupported |= feat.mValue; 482dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar mDefaultFormat.setInteger(key, 1); 483b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // TODO restrict features by mFlagsVerified once all codecs reliably verify them 484b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 485b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 486217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 487b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 488217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 489217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * A class that supports querying the audio capabilities of a codec. 490217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 491217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final class AudioCapabilities { 492217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final String TAG = "AudioCapabilities"; 493217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private CodecCapabilities mParent; 494217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mBitrateRange; 495217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 496217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int[] mSampleRates; 497217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer>[] mSampleRateRanges; 498217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mMaxInputChannelCount; 499217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 500217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int MAX_INPUT_CHANNEL_COUNT = 30; 501217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 502217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 503217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported bitrates in bits/second. 504217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 505217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getBitrateRange() { 506217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBitrateRange; 507217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 508217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 509217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 510217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the array of supported sample rates if the codec 511217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * supports only discrete values. Otherwise, it returns 512217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code null}. The array is sorted in ascending order. 513217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 514217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int[] getSupportedSampleRates() { 515217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return Arrays.copyOf(mSampleRates, mSampleRates.length); 516217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 517217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 518217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 519217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the array of supported sample rate ranges. The 520217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * array is sorted in ascending order, and the ranges are 521217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * distinct. 522217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 523217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer>[] getSupportedSampleRateRanges() { 524217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return Arrays.copyOf(mSampleRateRanges, mSampleRateRanges.length); 525217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 526217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 527217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 528217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the maximum number of input channels supported. The codec 529217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * supports any number of channels between 1 and this maximum value. 530217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 531217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getMaxInputChannelCount() { 532217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mMaxInputChannelCount; 533217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 534b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 535217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* no public constructor */ 536217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private AudioCapabilities() { } 537217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 538217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 539217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static AudioCapabilities create( 540217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MediaFormat info, CodecCapabilities parent) { 541217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar AudioCapabilities caps = new AudioCapabilities(); 542217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar caps.init(info, parent); 543217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return caps; 544217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 545217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 546217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 547217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void init(MediaFormat info, CodecCapabilities parent) { 548217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent = parent; 549217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar initWithPlatformLimits(); 550217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLevelLimits(); 551217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar parseFromInfo(info); 552217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 553217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 554217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void initWithPlatformLimits() { 555217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitrateRange = Range.create(0, Integer.MAX_VALUE); 556217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mMaxInputChannelCount = MAX_INPUT_CHANNEL_COUNT; 557217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // mBitrateRange = Range.create(1, 320000); 558217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges = new Range[] { Range.create(8000, 96000) }; 559217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates = null; 560217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 561217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 562217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean supports(Integer sampleRate, Integer inputChannels) { 563217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // channels and sample rates are checked orthogonally 564217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (inputChannels != null && 565217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (inputChannels < 1 || inputChannels > mMaxInputChannelCount)) { 566217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 567b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 568217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (sampleRate != null) { 569217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int ix = Utils.binarySearchDistinctRanges( 570217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges, sampleRate); 571217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ix < 0) { 572217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 573217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 574217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 575217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return true; 576217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 577b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 578217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 579217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Query whether the sample rate is supported by the codec. 580217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 581217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean isSampleRateSupported(int sampleRate) { 582217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(sampleRate, null); 583217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 584217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 585217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** modifies rates */ 586217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void limitSampleRates(int[] rates) { 587217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Arrays.sort(rates); 588217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>(); 589217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (int rate: rates) { 590217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (supports(rate, null /* channels */)) { 591217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ranges.add(Range.create(rate, rate)); 592217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 593b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 594217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges = ranges.toArray(new Range[ranges.size()]); 595217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar createDiscreteSampleRates(); 596217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 597b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 598217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void createDiscreteSampleRates() { 599217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates = new int[mSampleRateRanges.length]; 600217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (int i = 0; i < mSampleRateRanges.length; i++) { 601217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates[i] = mSampleRateRanges[i].getLower(); 602217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 603217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 604b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 605217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** modifies rateRanges */ 606217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void limitSampleRates(Range<Integer>[] rateRanges) { 607217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sortDistinctRanges(rateRanges); 608217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges); 609217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 610217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // check if all values are discrete 611217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Range<Integer> range: mSampleRateRanges) { 612217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!range.getLower().equals(range.getUpper())) { 613217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates = null; 614217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return; 615217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 616b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 617217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar createDiscreteSampleRates(); 618217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 619217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 620217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLevelLimits() { 621217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int[] sampleRates = null; 622217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> sampleRateRange = null, bitRates = null; 623217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxChannels = 0; 624217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String mime = mParent.getMimeType(); 625217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 626217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG)) { 627217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 628217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 8000, 11025, 12000, 629217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16000, 22050, 24000, 630217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 32000, 44100, 48000 }; 631217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(8000, 320000); 632217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 2; 633217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) { 634217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000 }; 635217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(4750, 12200); 636217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 1; 637217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)) { 638217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 16000 }; 639217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(6600, 23850); 640217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 1; 641217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) { 642217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 643217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 7350, 8000, 644217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 11025, 12000, 16000, 645217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 22050, 24000, 32000, 646217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 44100, 48000, 64000, 647217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 88200, 96000 }; 648217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(8000, 510000); 649217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 48; 650217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS)) { 651217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(32000, 500000); 652610e288de6727d9be3277777e6c5abca4b18aa86Lajos Molnar sampleRateRange = Range.create(8000, 192000); 653217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 255; 654217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS)) { 655217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(6000, 510000); 656217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000 }; 657217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 255; 658217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW)) { 659217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRateRange = Range.create(1, 96000); 660217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(1, 10000000); 661217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 8; 662217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) { 663217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRateRange = Range.create(1, 655350); 664217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // lossless codec, so bitrate is ignored 665217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 255; 666217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW) 667217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)) { 668217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000 }; 669217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(64000, 64000); 670217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // platform allows multiple channels for this format 671217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) { 672217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000 }; 673217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(13000, 13000); 674217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 1; 675217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else { 676217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unsupported mime " + mime); 677217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent.mError |= ERROR_UNSUPPORTED; 678217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 679217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 680217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // restrict ranges 681217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (sampleRates != null) { 682217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar limitSampleRates(sampleRates); 683217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (sampleRateRange != null) { 684217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar limitSampleRates(new Range[] { sampleRateRange }); 685217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 686217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLimits(maxChannels, bitRates); 687217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 688b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 689217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLimits(int maxInputChannels, Range<Integer> bitRates) { 690217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mMaxInputChannelCount = Range.create(1, mMaxInputChannelCount) 691217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar .clamp(maxInputChannels); 692217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (bitRates != null) { 693217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitrateRange = mBitrateRange.intersect(bitRates); 694b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 695217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 696217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 697217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void parseFromInfo(MediaFormat info) { 698217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxInputChannels = MAX_INPUT_CHANNEL_COUNT; 699217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> bitRates = POSITIVE_INTEGERS; 700b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 701217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("sample-rate-ranges")) { 702217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String[] rateStrings = info.getString("sample-rate-ranges").split(","); 703217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer>[] rateRanges = new Range[rateStrings.length]; 704217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (int i = 0; i < rateStrings.length; i++) { 705217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar rateRanges[i] = Utils.parseIntRange(rateStrings[i], null); 706217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 707217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar limitSampleRates(rateRanges); 708217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 709217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("max-channel-count")) { 710217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxInputChannels = Utils.parseIntSafely( 711217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar info.getString("max-channel-count"), maxInputChannels); 712217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 713217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("bitrate-range")) { 714217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = bitRates.intersect( 715216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang Utils.parseIntRange(info.getString("bitrate-range"), bitRates)); 716b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 717217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLimits(maxInputChannels, bitRates); 718217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 719b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 720217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 721217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void setDefaultFormat(MediaFormat format) { 722217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // report settings that have only a single choice 723217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) { 724217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower()); 725217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 726217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mMaxInputChannelCount == 1) { 727217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // mono-only format 728217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); 729217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 730217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mSampleRates != null && mSampleRates.length == 1) { 731217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRates[0]); 732217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 733217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 734217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 735217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 736217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean supportsFormat(MediaFormat format) { 737217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Map<String, Object> map = format.getMap(); 738217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE); 739217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT); 740217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!supports(sampleRate, channels)) { 741217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 742217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 743217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 744217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // nothing to do for: 745217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // KEY_CHANNEL_MASK: codecs don't get this 746217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // KEY_IS_ADTS: required feature for all AAC decoders 747217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return true; 748217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 749217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 750217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 751217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 752217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * A class that supports querying the video capabilities of a codec. 753217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 754217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final class VideoCapabilities { 755217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final String TAG = "VideoCapabilities"; 756217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private CodecCapabilities mParent; 757217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mBitrateRange; 758217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mHeightRange; 760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mWidthRange; 761217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mBlockCountRange; 762217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mHorizontalBlockRange; 763217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mVerticalBlockRange; 764217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Rational> mAspectRatioRange; 765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Rational> mBlockAspectRatioRange; 766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Long> mBlocksPerSecondRange; 767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mFrameRateRange; 768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 769217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mBlockWidth; 770217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mBlockHeight; 771217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mWidthAlignment; 772217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mHeightAlignment; 773217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mSmallerDimensionUpperLimit; 774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 775217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 776217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported bitrates in bits/second. 777217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 778217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getBitrateRange() { 779217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBitrateRange; 780217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 782217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 783217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video widths. 784217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 785217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedWidths() { 786217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mWidthRange; 787217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 788217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 789217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 790217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video heights. 791217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 792217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedHeights() { 793217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mHeightRange; 794217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 795217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 796217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 797217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the alignment requirement for video width (in pixels). 798217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 799217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is a power-of-2 value that video width must be a 800217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * multiple of. 801217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getWidthAlignment() { 803217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mWidthAlignment; 804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 805217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 806217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 807217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the alignment requirement for video height (in pixels). 808217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 809217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is a power-of-2 value that video height must be a 810217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * multiple of. 811217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 812217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getHeightAlignment() { 813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mHeightAlignment; 814217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 817217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Return the upper limit on the smaller dimension of width or height. 818217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p></p> 819217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Some codecs have a limit on the smaller dimension, whether it be 820217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * the width or the height. E.g. a codec may only be able to handle 821217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * up to 1920x1080 both in landscape and portrait mode (1080x1920). 822217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * In this case the maximum width and height are both 1920, but the 823217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * smaller dimension limit will be 1080. For other codecs, this is 824217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code Math.min(getSupportedWidths().getUpper(), 825217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * getSupportedHeights().getUpper())}. 826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 827217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @hide 828217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 829217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getSmallerDimensionUpperLimit() { 830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mSmallerDimensionUpperLimit; 831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 832217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 833217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported frame rates. 835217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p> 836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is not a performance indicator. Rather, it expresses the 837217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * limits specified in the coding standard, based on the complexities 838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * of encoding material for later playback at a certain frame rate, 839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * or the decoding of such material in non-realtime. 840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedFrameRates() { 842217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mFrameRateRange; 843217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 844217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 845217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 846217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video widths for a video height. 847217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param height the height of the video 848217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 849217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedWidthsFor(int height) { 850217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 851217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> range = mWidthRange; 852217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mHeightRange.contains(height) 853217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || (height % mHeightAlignment) != 0) { 854217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported height"); 855b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 856217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int heightInBlocks = Utils.divUp(height, mBlockHeight); 857217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 858217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by block count and by block aspect ratio 859217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int minWidthInBlocks = Math.max( 860217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.divUp(mBlockCountRange.getLower(), heightInBlocks), 861217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(mBlockAspectRatioRange.getLower().doubleValue() 862217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * heightInBlocks)); 863217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int maxWidthInBlocks = Math.min( 864217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / heightInBlocks, 865217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mBlockAspectRatioRange.getUpper().doubleValue() 866217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * heightInBlocks)); 867217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 868217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (minWidthInBlocks - 1) * mBlockWidth + mWidthAlignment, 869217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxWidthInBlocks * mBlockWidth); 870217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 871217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by smaller dimension limit 872217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (height > mSmallerDimensionUpperLimit) { 873217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect(1, mSmallerDimensionUpperLimit); 874b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 875b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 876217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by aspect ratio 877217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 878217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(mAspectRatioRange.getLower().doubleValue() 879217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * height), 880217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mAspectRatioRange.getUpper().doubleValue() * height)); 881217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return range; 882217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 883217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // should not be here 884217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "could not get supported widths for " + height , e); 885217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported height"); 886b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 887217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 888b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 889217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 890217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video heights for a video width 891217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param width the width of the video 892217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 893217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedHeightsFor(int width) { 894217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 895217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> range = mHeightRange; 896217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mWidthRange.contains(width) 897217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || (width % mWidthAlignment) != 0) { 898217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported width"); 899b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 900217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int widthInBlocks = Utils.divUp(width, mBlockWidth); 901217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 902217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by block count and by block aspect ratio 903217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int minHeightInBlocks = Math.max( 904217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.divUp(mBlockCountRange.getLower(), widthInBlocks), 905217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(widthInBlocks / 906217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange.getUpper().doubleValue())); 907217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int maxHeightInBlocks = Math.min( 908217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / widthInBlocks, 909217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(widthInBlocks / 910217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange.getLower().doubleValue())); 911217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 912217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (minHeightInBlocks - 1) * mBlockHeight + mHeightAlignment, 913217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxHeightInBlocks * mBlockHeight); 914217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 915217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by smaller dimension limit 916217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (width > mSmallerDimensionUpperLimit) { 917217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect(1, mSmallerDimensionUpperLimit); 918217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 919217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 920217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by aspect ratio 921217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 922217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(width / 923217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange.getUpper().doubleValue()), 924217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(width / mAspectRatioRange.getLower().doubleValue())); 925217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return range; 926217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 927217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // should not be here 928217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "could not get supported heights for " + width , e); 929217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported width"); 930217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 931217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 932217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 933217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 934217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video frame rates for a video size. 935217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p> 936217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is not a performance indicator. Rather, it expresses the limits specified in 937217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * the coding standard, based on the complexities of encoding material of a given 938217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * size for later playback at a certain frame rate, or the decoding of such material 939217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * in non-realtime. 940217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 941217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param width the width of the video 942217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param height the height of the video 943217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 944217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Double> getSupportedFrameRatesFor(int width, int height) { 945217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> range = mHeightRange; 946217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!supports(width, height, null)) { 947217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported size"); 948217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 949217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int blockCount = 950217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight); 951217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 952217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return Range.create( 953217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.max(mBlocksPerSecondRange.getLower() / (double) blockCount, 954217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (double) mFrameRateRange.getLower()), 955217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(mBlocksPerSecondRange.getUpper() / (double) blockCount, 956217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (double) mFrameRateRange.getUpper())); 957217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 958217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 959217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 960217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns whether a given video size ({@code width} and 961217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code height}) and {@code frameRate} combination is supported. 962217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 963217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean areSizeAndRateSupported( 964217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int width, int height, double frameRate) { 965217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(width, height, frameRate); 966217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 967217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 968217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 969217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns whether a given video size ({@code width} and 970217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code height}) is supported. 971217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 972217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean isSizeSupported(int width, int height) { 973217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(width, height, null); 974217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 975217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 976217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean supports( 977a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar Integer width, Integer height, Number rate) { 978217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean ok = true; 979217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 980217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && width != null) { 981217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mWidthRange.contains(width) 982217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && (width % mWidthAlignment == 0); 983217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 984217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && height != null) { 985217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mHeightRange.contains(height) 986217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && (height % mHeightAlignment == 0); 987b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 988217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && rate != null) { 989a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar ok = mFrameRateRange.contains(Utils.intRangeFor(rate.doubleValue())); 990217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 991217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && height != null && width != null) { 992217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = Math.min(height, width) <= mSmallerDimensionUpperLimit; 993b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 994217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int widthInBlocks = Utils.divUp(width, mBlockWidth); 995217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int heightInBlocks = Utils.divUp(height, mBlockHeight); 996217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int blockCount = widthInBlocks * heightInBlocks; 997217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = ok && mBlockCountRange.contains(blockCount) 998217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mBlockAspectRatioRange.contains( 999217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(widthInBlocks, heightInBlocks)) 1000217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mAspectRatioRange.contains(new Rational(width, height)); 1001217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && rate != null) { 1002a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar double blocksPerSec = blockCount * rate.doubleValue(); 1003217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mBlocksPerSecondRange.contains( 1004217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.longRangeFor(blocksPerSec)); 1005b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1006b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1007217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return ok; 1008217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1009b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1010217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1011217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @hide 1012217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @throws java.lang.ClassCastException */ 1013217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean supportsFormat(MediaFormat format) { 1014217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final Map<String, Object> map = format.getMap(); 1015217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer width = (Integer)map.get(MediaFormat.KEY_WIDTH); 1016217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT); 1017a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE); 1018217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1019217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // we ignore color-format for now as it is not reliably reported by codec 1020217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1021217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(width, height, rate); 1022217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1023217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1024217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* no public constructor */ 1025217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private VideoCapabilities() { } 1026217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1027217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1028217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static VideoCapabilities create( 1029217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MediaFormat info, CodecCapabilities parent) { 1030217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar VideoCapabilities caps = new VideoCapabilities(); 1031217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar caps.init(info, parent); 1032217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return caps; 1033217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1034217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1035217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1036217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void init(MediaFormat info, CodecCapabilities parent) { 1037217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent = parent; 1038217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar initWithPlatformLimits(); 1039217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLevelLimits(); 1040217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar parseFromInfo(info); 1041217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar updateLimits(); 1042217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1043217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1044217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1045217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Size getBlockSize() { 1046217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return new Size(mBlockWidth, mBlockHeight); 1047217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1048217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1049217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1050217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getBlockCountRange() { 1051217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBlockCountRange; 1052217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1053217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1054217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1055217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Long> getBlocksPerSecondRange() { 1056217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBlocksPerSecondRange; 1057217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1058b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1059217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1060217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Rational> getAspectRatioRange(boolean blocks) { 1061217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return blocks ? mBlockAspectRatioRange : mAspectRatioRange; 1062217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1063217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1064217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void initWithPlatformLimits() { 1065216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang mBitrateRange = BITRATE_RANGE; 1066217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1067217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = SIZE_RANGE; 1068217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = SIZE_RANGE; 1069217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = FRAME_RATE_RANGE; 1070217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1071217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = SIZE_RANGE; 1072217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = SIZE_RANGE; 1073217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1074217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // full positive ranges are supported as these get calculated 1075217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = POSITIVE_INTEGERS; 1076217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = POSITIVE_LONGS; 1077217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1078217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = POSITIVE_RATIONALS; 1079217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = POSITIVE_RATIONALS; 1080217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1081217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // YUV 4:2:0 requires 2:2 alignment 1082217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthAlignment = 2; 1083217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightAlignment = 2; 1084217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth = 2; 1085217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight = 2; 1086217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper(); 1087217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1088217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1089217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void parseFromInfo(MediaFormat info) { 1090217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final Map<String, Object> map = info.getMap(); 1091217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Size blockSize = new Size(mBlockWidth, mBlockHeight); 1092217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Size alignment = new Size(mWidthAlignment, mHeightAlignment); 1093217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> counts = null, widths = null, heights = null; 1094216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang Range<Integer> frameRates = null, bitRates = null; 1095217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Long> blockRates = null; 1096217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Rational> ratios = null, blockRatios = null; 1097217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1098217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockSize = Utils.parseSize(map.get("block-size"), blockSize); 1099217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment = Utils.parseSize(map.get("alignment"), alignment); 1100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar counts = Utils.parseIntRange(map.get("block-count-range"), null); 1101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockRates = 1102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.parseLongRange(map.get("blocks-per-second-range"), null); 1103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar { 1104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Object o = map.get("size-range"); 1105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Pair<Size, Size> sizeRange = Utils.parseSizeRange(o); 1106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (sizeRange != null) { 1107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar widths = Range.create( 1109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sizeRange.first.getWidth(), 1110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sizeRange.second.getWidth()); 1111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar heights = Range.create( 1112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sizeRange.first.getHeight(), 1113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sizeRange.second.getHeight()); 1114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 1115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "could not parse size range '" + o + "'"); 1116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar widths = null; 1117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar heights = null; 1118b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1119b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1120b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // for now this just means using the smaller max size as 2nd 1122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // upper limit. 1123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // for now we are keeping the profile specific "width/height 1124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // in macroblocks" limits. 1125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (Integer.valueOf(1).equals(map.get("feature-can-swap-width-height"))) { 1126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widths != null) { 1127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = 1128217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(widths.getUpper(), heights.getUpper()); 1129217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar widths = heights = widths.extend(heights); 1130981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } else { 1131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "feature can-swap-width-height is best used with size-range"); 1132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = 1133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(mWidthRange.getUpper(), mHeightRange.getUpper()); 1134217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange); 1135b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1136b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1137b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ratios = Utils.parseRationalRange( 1139217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar map.get("block-aspect-ratio-range"), null); 1140217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockRatios = Utils.parseRationalRange( 1141217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar map.get("pixel-aspect-ratio-range"), null); 1142217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar frameRates = Utils.parseIntRange(map.get("frame-rate-range"), null); 1143217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (frameRates != null) { 1144217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1145217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar frameRates = frameRates.intersect(FRAME_RATE_RANGE); 1146217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 1147217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "frame rate range (" + frameRates 1148217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + ") is out of limits: " + FRAME_RATE_RANGE); 1149217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar frameRates = null; 1150b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1151b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1152216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang bitRates = Utils.parseIntRange(map.get("bitrate-range"), null); 1153216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang if (bitRates != null) { 1154216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang try { 1155216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang bitRates = bitRates.intersect(BITRATE_RANGE); 1156216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } catch (IllegalArgumentException e) { 1157216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang Log.w(TAG, "bitrate range (" + bitRates 1158216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang + ") is out of limits: " + BITRATE_RANGE); 1159216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang bitRates = null; 1160216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1161216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1162b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1163217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1164217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockSize.getWidth(), "block-size width must be power of two"); 1165217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1166217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockSize.getHeight(), "block-size height must be power of two"); 1167b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1168217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1169217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment.getWidth(), "alignment width must be power of two"); 1170217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1171217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment.getHeight(), "alignment height must be power of two"); 1172217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1173217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // update block-size and alignment 1174217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits( 1175217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 1176217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(), 1177217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment.getWidth(), alignment.getHeight()); 1178217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1179217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if ((mParent.mError & ERROR_UNSUPPORTED) != 0) { 1180217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // codec supports profiles that we don't know. 1181217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // Use supplied values clipped to platform limits 1182217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widths != null) { 1183217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = SIZE_RANGE.intersect(widths); 1184217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1185217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (heights != null) { 1186217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = SIZE_RANGE.intersect(heights); 1187217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1188217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (counts != null) { 1189217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = POSITIVE_INTEGERS.intersect( 1190217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(counts, mBlockWidth * mBlockHeight 1191217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1192217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1193217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRates != null) { 1194217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = POSITIVE_LONGS.intersect( 1195217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(blockRates, mBlockWidth * mBlockHeight 1196217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1197217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1198217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRatios != null) { 1199217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect( 1200217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.scaleRange(blockRatios, 1201217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight / blockSize.getHeight(), 1202217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth / blockSize.getWidth())); 1203217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1204217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ratios != null) { 1205217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios); 1206217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1207217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (frameRates != null) { 1208217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates); 1209217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1210216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang if (bitRates != null) { 1211216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang mBitrateRange = BITRATE_RANGE.intersect(bitRates); 1212216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1213217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else { 1214217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // no unsupported profile/levels, so restrict values to known limits 1215217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widths != null) { 1216217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = mWidthRange.intersect(widths); 1217217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1218217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (heights != null) { 1219217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = mHeightRange.intersect(heights); 1220b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1221217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (counts != null) { 1222217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = mBlockCountRange.intersect( 1223217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(counts, mBlockWidth * mBlockHeight 1224217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1225b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1226217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRates != null) { 1227217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = mBlocksPerSecondRange.intersect( 1228217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(blockRates, mBlockWidth * mBlockHeight 1229217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1230b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1231217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRatios != null) { 1232217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = mBlockAspectRatioRange.intersect( 1233217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.scaleRange(blockRatios, 1234217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight / blockSize.getHeight(), 1235217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth / blockSize.getWidth())); 1236217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1237217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ratios != null) { 1238217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = mAspectRatioRange.intersect(ratios); 1239217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1240217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (frameRates != null) { 1241217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = mFrameRateRange.intersect(frameRates); 1242217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1243216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang if (bitRates != null) { 1244216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang mBitrateRange = mBitrateRange.intersect(bitRates); 1245216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1246217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1247217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar updateLimits(); 1248217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1249217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1250217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyBlockLimits( 1251217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int blockWidth, int blockHeight, 1252217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> counts, Range<Long> rates, Range<Rational> ratios) { 1253217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(blockWidth, "blockWidth must be a power of two"); 1254217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(blockHeight, "blockHeight must be a power of two"); 1255217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1256217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int newBlockWidth = Math.max(blockWidth, mBlockWidth); 1257217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int newBlockHeight = Math.max(blockHeight, mBlockHeight); 1258217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1259217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // factor will always be a power-of-2 1260217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int factor = 1261217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight; 1262217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (factor != 1) { 1263217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = Utils.factorRange(mBlockCountRange, factor); 1264217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = Utils.factorRange( 1265217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange, factor); 1266217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = Utils.scaleRange( 1267217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange, 1268217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockHeight / mBlockHeight, 1269217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockWidth / mBlockWidth); 1270217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = Utils.factorRange( 1271217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange, newBlockWidth / mBlockWidth); 1272217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = Utils.factorRange( 1273217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange, newBlockHeight / mBlockHeight); 1274217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1275217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight; 1276217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (factor != 1) { 1277217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar counts = Utils.factorRange(counts, factor); 1278217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar rates = Utils.factorRange(rates, factor); 1279217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ratios = Utils.scaleRange( 1280217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ratios, newBlockHeight / blockHeight, 1281217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockWidth / blockWidth); 1282217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1283217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = mBlockCountRange.intersect(counts); 1284217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates); 1285217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios); 1286217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth = newBlockWidth; 1287217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight = newBlockHeight; 1288217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1289217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1290217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyAlignment(int widthAlignment, int heightAlignment) { 1291217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(widthAlignment, "widthAlignment must be a power of two"); 1292217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(heightAlignment, "heightAlignment must be a power of two"); 1293217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1294217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) { 1295217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // maintain assumption that 0 < alignment <= block-size 1296217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyBlockLimits( 1297217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.max(widthAlignment, mBlockWidth), 1298217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.max(heightAlignment, mBlockHeight), 1299217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar POSITIVE_INTEGERS, POSITIVE_LONGS, POSITIVE_RATIONALS); 1300b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1301b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1302217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthAlignment = Math.max(widthAlignment, mWidthAlignment); 1303217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightAlignment = Math.max(heightAlignment, mHeightAlignment); 1304217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1305217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = Utils.alignRange(mWidthRange, mWidthAlignment); 1306217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = Utils.alignRange(mHeightRange, mHeightAlignment); 1307217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1308217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1309217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void updateLimits() { 1310217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // pixels -> blocks <- counts 1311217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = mHorizontalBlockRange.intersect( 1312217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(mWidthRange, mBlockWidth)); 1313217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = mHorizontalBlockRange.intersect( 1314217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1315217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getLower() / mVerticalBlockRange.getUpper(), 1316217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / mVerticalBlockRange.getLower())); 1317217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = mVerticalBlockRange.intersect( 1318217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(mHeightRange, mBlockHeight)); 1319217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = mVerticalBlockRange.intersect( 1320217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1321217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getLower() / mHorizontalBlockRange.getUpper(), 1322217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / mHorizontalBlockRange.getLower())); 1323217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = mBlockCountRange.intersect( 1324217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1325217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getLower() 1326217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * mVerticalBlockRange.getLower(), 1327217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getUpper() 1328217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * mVerticalBlockRange.getUpper())); 1329217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = mBlockAspectRatioRange.intersect( 1330217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational( 1331217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getLower(), mVerticalBlockRange.getUpper()), 1332217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational( 1333217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getUpper(), mVerticalBlockRange.getLower())); 1334217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1335217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // blocks -> pixels 1336217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = mWidthRange.intersect( 1337217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (mHorizontalBlockRange.getLower() - 1) * mBlockWidth + mWidthAlignment, 1338217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getUpper() * mBlockWidth); 1339217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = mHeightRange.intersect( 1340217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (mVerticalBlockRange.getLower() - 1) * mBlockHeight + mHeightAlignment, 1341217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange.getUpper() * mBlockHeight); 1342217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = mAspectRatioRange.intersect( 1343217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(mWidthRange.getLower(), mHeightRange.getUpper()), 1344217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(mWidthRange.getUpper(), mHeightRange.getLower())); 1345217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1346217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = Math.min( 1347217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit, 1348217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(mWidthRange.getUpper(), mHeightRange.getUpper())); 1349217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1350217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // blocks -> rate 1351217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = mBlocksPerSecondRange.intersect( 1352217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getLower() * (long)mFrameRateRange.getLower(), 1353217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() * (long)mFrameRateRange.getUpper()); 1354217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = mFrameRateRange.intersect( 1355217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mBlocksPerSecondRange.getLower() 1356217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / mBlockCountRange.getUpper()), 1357217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mBlocksPerSecondRange.getUpper() 1358217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / (double)mBlockCountRange.getLower())); 1359217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1360217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1361217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyMacroBlockLimits( 1362217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxHorizontalBlocks, int maxVerticalBlocks, 1363217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBlocks, long maxBlocksPerSecond, 1364217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int blockWidth, int blockHeight, 1365217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int widthAlignment, int heightAlignment) { 1366217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyAlignment(widthAlignment, heightAlignment); 1367217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyBlockLimits( 1368217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockWidth, blockHeight, Range.create(1, maxBlocks), 1369217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(1L, maxBlocksPerSecond), 1370217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1371217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(1, maxVerticalBlocks), 1372217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(maxHorizontalBlocks, 1))); 1373217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = 1374217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.intersect( 1375217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1, maxHorizontalBlocks / (mBlockWidth / blockWidth)); 1376217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = 1377217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange.intersect( 1378217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1, maxVerticalBlocks / (mBlockHeight / blockHeight)); 1379217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1380217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1381217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLevelLimits() { 1382217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBlocksPerSecond = 0; 1383217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBlocks = 0; 1384217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBps = 0; 1385217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxDPBBlocks = 0; 1386217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1387217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int errors = ERROR_NONE_SUPPORTED; 1388217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar CodecProfileLevel[] profileLevels = mParent.profileLevels; 1389217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String mime = mParent.getMimeType(); 1390217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1391217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) { 1392217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 99; 1393217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = 1485; 1394217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 1395217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxDPBBlocks = 396; 1396217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 1397217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int MBPS = 0, FS = 0, BR = 0, DPB = 0; 1398217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean supported = true; 1399217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 1400217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel1: 1401217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 1485; FS = 99; BR = 64; DPB = 396; break; 1402217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel1b: 1403217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 1485; FS = 99; BR = 128; DPB = 396; break; 1404217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel11: 1405217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 3000; FS = 396; BR = 192; DPB = 900; break; 1406217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel12: 1407217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 6000; FS = 396; BR = 384; DPB = 2376; break; 1408217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel13: 1409217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 11880; FS = 396; BR = 768; DPB = 2376; break; 1410217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel2: 1411217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 11880; FS = 396; BR = 2000; DPB = 2376; break; 1412217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel21: 1413217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 19800; FS = 792; BR = 4000; DPB = 4752; break; 1414217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel22: 1415217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 20250; FS = 1620; BR = 4000; DPB = 8100; break; 1416217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel3: 1417217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 40500; FS = 1620; BR = 10000; DPB = 8100; break; 1418217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel31: 1419217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 108000; FS = 3600; BR = 14000; DPB = 18000; break; 1420217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel32: 1421217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 216000; FS = 5120; BR = 20000; DPB = 20480; break; 1422217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel4: 1423217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 245760; FS = 8192; BR = 20000; DPB = 32768; break; 1424217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel41: 1425217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 245760; FS = 8192; BR = 50000; DPB = 32768; break; 1426217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel42: 1427217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 522240; FS = 8704; BR = 50000; DPB = 34816; break; 1428217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel5: 1429217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 589824; FS = 22080; BR = 135000; DPB = 110400; break; 1430217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel51: 1431217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 983040; FS = 36864; BR = 240000; DPB = 184320; break; 1432217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel52: 1433217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break; 1434217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1435217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized level " 1436217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 1437217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1438217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1439217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 1440217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh: 1441217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 1250; break; 1442217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh10: 1443217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 3000; break; 1444217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileExtended: 1445217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh422: 1446217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh444: 1447217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unsupported profile " 1448217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1449217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNSUPPORTED; 1450217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar supported = false; 1451217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // fall through - treat as base profile 1452217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileBaseline: 1453217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileMain: 1454217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 1000; break; 1455217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1456217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 1457217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1458217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1459217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 1000; 1460217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1461217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (supported) { 1462217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 1463217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1464217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 1465217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(FS, maxBlocks); 1466217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR, maxBps); 1467217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxDPBBlocks = Math.max(maxDPBBlocks, DPB); 1468981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } 1469217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1470217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8)); 1471217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits( 1472217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxLengthInBlocks, maxLengthInBlocks, 1473217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 1474217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16 /* blockWidth */, 16 /* blockHeight */, 1475217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 1476217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) { 1477217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxWidth = 11, maxHeight = 9, maxRate = 15; 1478217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 99; 1479217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = 1485; 1480217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 1481217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 1482217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0; 1483217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean supported = true; 1484217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 1485217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimple: 1486217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 1487217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level0: 1488217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break; 1489217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level1: 1490217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break; 1491217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level0b: 1492217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 128; break; 1493217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level2: 1494217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 5940; FS = 396; BR = 128; break; 1495217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level3: 1496217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break; 1497217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level4: 1498217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level4a: 1499217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level5: 1500217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // While MPEG4 SP does not have level 4 or 5, some vendors 1501217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // report it. Use the same limits as level 3, but mark as 1502217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // unsupported. 1503217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; 1504217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar supported = false; 1505217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1506217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1507217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile/level " 1508217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + "/" 1509217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 1510217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1511217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1512217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1513217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedSimple: 1514217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 1515217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level0: 1516217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level1: 1517217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 11; H = 9; MBPS = 2970; FS = 99; BR = 128; break; 1518217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level2: 1519217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 5940; FS = 396; BR = 384; break; 1520217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level3: 1521217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 768; break; 1522217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // case CodecProfileLevel.MPEG4Level3b: 1523217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // TODO: MPEG4 level 3b is not defined in OMX 1524217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // MBPS = 11880; FS = 396; BR = 1500; break; 1525217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level4: 1526217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level4a: 1527217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // TODO: MPEG4 level 4a is not defined in spec 1528217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 44; H = 36; MBPS = 23760; FS = 792; BR = 3000; break; 1529217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level5: 1530217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break; 1531217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1532217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile/level " 1533217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + "/" 1534217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 1535217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1536217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1537217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1538217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileMain: // 2-4 1539217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileNbit: // 2 1540217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedRealTime: // 1-4 1541217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileCoreScalable: // 1-3 1542217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedCoding: // 1-4 1543217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileCore: // 1-2 1544217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedCore: // 1-4 1545217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimpleScalable: // 0-2 1546217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3 1547217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileHybrid: // 1-2 1548217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileBasicAnimated: // 1-2 1549217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileScalableTexture: // 1 1550217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimpleFace: // 1-2 1551217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimpleFBA: // 1-2 1552217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.i(TAG, "Unsupported profile " 1553217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1554217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNSUPPORTED; 1555217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar supported = false; 1556217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1557217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1558217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 1559217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1560217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1561217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1562217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (supported) { 1563217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 1564217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1565217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 1566217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(FS, maxBlocks); 1567217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR * 1000, maxBps); 1568217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxWidth = Math.max(W, maxWidth); 1569217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxHeight = Math.max(H, maxHeight); 1570217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxRate = Math.max(FR, maxRate); 1571981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } 1572217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits(maxWidth, maxHeight, 1573217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 1574217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16 /* blockWidth */, 16 /* blockHeight */, 1575217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 1576217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = mFrameRateRange.intersect(12, maxRate); 1577217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) { 1578217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxWidth = 11, maxHeight = 9, maxRate = 15; 1579217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 99; 1580217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = 1485; 1581217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 1582217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 1583217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0; 1584217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 1585217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level10: 1586217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 15; W = 11; H = 9; BR = 1; MBPS = W * H * FR; break; 1587217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level20: 1588217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports CIF, 0..QCIF 1589217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; BR = 2; MBPS = W * H * FR; break; 1590217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level30: 1591217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports CIF, 0..QCIF 1592217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; BR = 6; MBPS = W * H * FR; break; 1593217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level40: 1594217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports CIF, 0..QCIF 1595217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; BR = 32; MBPS = W * H * FR; break; 1596217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level45: 1597217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only implies level 10 support 1598217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 11; H = 9; BR = 2; MBPS = W * H * FR; break; 1599217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level50: 1600217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports 50fps for H > 15 1601217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; W = 22; H = 18; BR = 64; MBPS = W * H * 50; break; 1602217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level60: 1603217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports 50fps for H > 15 1604217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; W = 45; H = 18; BR = 128; MBPS = W * H * 50; break; 1605217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level70: 1606217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports 50fps for H > 30 1607217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; W = 45; H = 36; BR = 256; MBPS = W * H * 50; break; 1608217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1609217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile 1610217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + "/" + profileLevel.level + " for " + mime); 1611217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1612217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1613217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 1614217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileBackwardCompatible: 1615217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileBaseline: 1616217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileH320Coding: 1617217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileHighCompression: 1618217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileHighLatency: 1619217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileInterlace: 1620217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileInternet: 1621217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileISWV2: 1622217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileISWV3: 1623217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1624217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1625217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 1626217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1627217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1628217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1629217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 1630217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 1631217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(W * H, maxBlocks); 1632217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR * 64000, maxBps); 1633217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxWidth = Math.max(W, maxWidth); 1634217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxHeight = Math.max(H, maxHeight); 1635217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxRate = Math.max(FR, maxRate); 1636217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1637217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits(maxWidth, maxHeight, 1638217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 1639217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16 /* blockWidth */, 16 /* blockHeight */, 1640217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 1641217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = Range.create(1, maxRate); 1642217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) || 1643217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) { 1644217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = maxBlocksPerSecond = Integer.MAX_VALUE; 1645217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1646217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // TODO: set to 100Mbps for now, need a number for VPX 1647217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 100000000; 1648217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1649217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // profile levels are not indicative for VPx, but verify 1650217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // them nonetheless 1651217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 1652217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 1653217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version0: 1654217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version1: 1655217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version2: 1656217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version3: 1657217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1658217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1659217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized level " 1660217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 1661217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1662217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1663217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 1664217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8ProfileMain: 1665217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1666217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1667217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 1668217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1669217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1670217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1671217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 1672981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } 1673981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar 1674217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int blockSize = 1675217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8) ? 16 : 8; 1676217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE, 1677217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, blockSize, blockSize, 1678217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 1679217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) { 1680217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 36864; 1681217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = maxBlocks * 15; 1682217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 128000; 1683217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 1684217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar double FR = 0; 1685217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int FS = 0; 1686217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int BR = 0; 1687217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 1688217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel1: 1689217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel1: 1690217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 15; FS = 36864; BR = 128; break; 1691217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel2: 1692217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel2: 1693217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 122880; BR = 1500; break; 1694217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel21: 1695217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel21: 1696217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 245760; BR = 3000; break; 1697217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel3: 1698217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel3: 1699217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 552960; BR = 6000; break; 1700217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel31: 1701217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel31: 1702217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 33.75; FS = 983040; BR = 10000; break; 1703217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel4: 1704217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 2228224; BR = 12000; break; 1705217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel4: 1706217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 2228224; BR = 30000; break; 1707217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel41: 1708217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 2228224; BR = 20000; break; 1709217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel41: 1710217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 2228224; BR = 50000; break; 1711217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel5: 1712217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 8912896; BR = 25000; break; 1713217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel5: 1714217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 8912896; BR = 100000; break; 1715217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel51: 1716217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 8912896; BR = 40000; break; 1717217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel51: 1718217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 8912896; BR = 160000; break; 1719217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel52: 1720217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 8912896; BR = 60000; break; 1721217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel52: 1722217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 8912896; BR = 240000; break; 1723217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel6: 1724217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 35651584; BR = 60000; break; 1725217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel6: 1726217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 35651584; BR = 240000; break; 1727217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel61: 1728217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 35651584; BR = 120000; break; 1729217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel61: 1730217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 35651584; BR = 480000; break; 1731217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel62: 1732217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 35651584; BR = 240000; break; 1733217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel62: 1734217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 35651584; BR = 800000; break; 1735217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1736217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized level " 1737217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 1738217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1739217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1740217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 1741217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCProfileMain: 1742217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCProfileMain10: 1743217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1744217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 1745217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 1746217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 1747217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 1748217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1749217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1750217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* DPB logic: 1751217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (width * height <= FS / 4) DPB = 16; 1752217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar else if (width * height <= FS / 2) DPB = 12; 1753217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar else if (width * height <= FS * 0.75) DPB = 8; 1754217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar else DPB = 6; 1755217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1756217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1757217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 1758217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond); 1759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(FS, maxBlocks); 1760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR * 1000, maxBps); 1761b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1762b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1763217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8)); 1764217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // CTBs are at least 8x8 1765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Utils.divUp(maxBlocks, 8 * 8); 1766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, 8 * 8); 1767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxLengthInBlocks = Utils.divUp(maxLengthInBlocks, 8); 1768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1769217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits( 1770217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxLengthInBlocks, maxLengthInBlocks, 1771217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 1772217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 8 /* blockWidth */, 8 /* blockHeight */, 1773217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 1774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else { 1775217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unsupported mime " + mime); 1776217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // using minimal bitrate here. should be overriden by 1777217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // info from media_codecs.xml 1778217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 1779217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNSUPPORTED; 1780217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitrateRange = Range.create(1, maxBps); 1782217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent.mError |= errors; 1783217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1784217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1785217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1786217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1787217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * A class that supports querying the encoding capabilities of a codec. 1788217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1789217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final class EncoderCapabilities { 1790217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1791217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the supported range of quality values. 1792217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 1793217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @hide 1794217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1795217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getQualityRange() { 1796217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mQualityRange; 1797217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1798217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1799217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1800217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the supported range of encoder complexity values. 1801217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p> 1802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Some codecs may support multiple complexity levels, where higher 1803217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * complexity values use more encoder tools (e.g. perform more 1804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * intensive calculations) to improve the quality or the compression 1805217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * ratio. Use a lower value to save power and/or time. 1806217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1807217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getComplexityRange() { 1808217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mComplexityRange; 1809217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1810217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1811217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** Constant quality mode */ 1812217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final int BITRATE_MODE_CQ = 0; 1813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** Variable bitrate mode */ 1814217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final int BITRATE_MODE_VBR = 1; 1815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** Constant bitrate mode */ 1816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final int BITRATE_MODE_CBR = 2; 1817217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1818217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Feature[] bitrates = new Feature[] { 1819217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Feature("VBR", BITRATE_MODE_VBR, true), 1820217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Feature("CBR", BITRATE_MODE_CBR, false), 1821217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Feature("CQ", BITRATE_MODE_CQ, false) 1822b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar }; 1823b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1824217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static int parseBitrateMode(String mode) { 1825217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Feature feat: bitrates) { 1826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (feat.mName.equalsIgnoreCase(mode)) { 1827217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return feat.mValue; 1828217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1829217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return 0; 1831b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1832b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1833b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 1834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Query whether a bitrate mode is supported. 1835b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 1836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean isBitrateModeSupported(int mode) { 1837217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Feature feat: bitrates) { 1838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mode == feat.mValue) { 1839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return (mBitControl & (1 << mode)) != 0; 1840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1842217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 1843b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1844b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1845217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mQualityRange; 1846217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mComplexityRange; 1847217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private CodecCapabilities mParent; 1848217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1849217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* no public constructor */ 1850217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private EncoderCapabilities() { } 1851217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1852b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 1853217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static EncoderCapabilities create( 1854217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MediaFormat info, CodecCapabilities parent) { 1855217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar EncoderCapabilities caps = new EncoderCapabilities(); 1856217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar caps.init(info, parent); 1857217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return caps; 1858217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1859217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1860217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1861217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void init(MediaFormat info, CodecCapabilities parent) { 1862217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // no support for complexity or quality yet 1863217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent = parent; 1864217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mComplexityRange = Range.create(0, 0); 1865217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mQualityRange = Range.create(0, 0); 1866217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl = (1 << BITRATE_MODE_VBR); 1867217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1868217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLevelLimits(); 1869217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar parseFromInfo(info); 1870217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1871217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1872217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLevelLimits() { 1873217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String mime = mParent.getMimeType(); 1874217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) { 1875217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mComplexityRange = Range.create(0, 8); 1876217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl = (1 << BITRATE_MODE_CQ); 1877217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB) 1878217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB) 1879217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW) 1880217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW) 1881217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) { 1882217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl = (1 << BITRATE_MODE_CBR); 1883217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1884217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1885217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1886217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mBitControl; 1887217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Integer mDefaultComplexity; 1888217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Integer mDefaultQuality; 1889217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private String mQualityScale; 1890217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1891217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void parseFromInfo(MediaFormat info) { 1892217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Map<String, Object> map = info.getMap(); 1893217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1894217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("complexity-range")) { 1895217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mComplexityRange = Utils 1896217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar .parseIntRange(info.getString("complexity-range"), mComplexityRange); 1897217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // TODO should we limit this to level limits? 1898217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1899217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("quality-range")) { 1900217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mQualityRange = Utils 1901217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar .parseIntRange(info.getString("quality-range"), mQualityRange); 1902217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1903217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("feature-bitrate-control")) { 1904217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (String mode: info.getString("feature-bitrate-control").split(",")) { 1905217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl |= parseBitrateMode(mode); 1906217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1907217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1908217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1909217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1910217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefaultComplexity = Integer.parseInt((String)map.get("complexity-default")); 1911217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (NumberFormatException e) { } 1912217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1913217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1914217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefaultQuality = Integer.parseInt((String)map.get("quality-default")); 1915217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (NumberFormatException e) { } 1916217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1917217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mQualityScale = (String)map.get("quality-scale"); 1918217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1919217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1920217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean supports( 1921217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer complexity, Integer quality, Integer profile) { 1922217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean ok = true; 1923217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && complexity != null) { 1924217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mComplexityRange.contains(complexity); 1925217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1926217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && quality != null) { 1927217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mQualityRange.contains(quality); 1928217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1929217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && profile != null) { 1930217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel pl: mParent.profileLevels) { 1931217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (pl.profile == profile) { 1932217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar profile = null; 1933217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1934217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1935217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1936217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = profile == null; 1937217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1938217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return ok; 1939217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1940217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1941217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1942217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void setDefaultFormat(MediaFormat format) { 1943217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // don't list trivial quality/complexity as default for now 1944217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mQualityRange.getUpper().equals(mQualityRange.getLower()) 1945217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mDefaultQuality != null) { 1946217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_QUALITY, mDefaultQuality); 1947217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1948217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mComplexityRange.getUpper().equals(mComplexityRange.getLower()) 1949217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mDefaultComplexity != null) { 1950217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_COMPLEXITY, mDefaultComplexity); 1951217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1952217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // bitrates are listed in order of preference 1953217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Feature feat: bitrates) { 1954217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if ((mBitControl & (1 << feat.mValue)) != 0) { 1955217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_BITRATE_MODE, feat.mValue); 1956217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 1957217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1958217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1959217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1960217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1961217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1962217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean supportsFormat(MediaFormat format) { 1963217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final Map<String, Object> map = format.getMap(); 1964217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final String mime = mParent.getMimeType(); 1965217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1966217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer mode = (Integer)map.get(MediaFormat.KEY_BITRATE_MODE); 1967217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mode != null && !isBitrateModeSupported(mode)) { 1968217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 1969217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1970217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1971217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer complexity = (Integer)map.get(MediaFormat.KEY_COMPLEXITY); 1972217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (MediaFormat.MIMETYPE_AUDIO_FLAC.equalsIgnoreCase(mime)) { 1973217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer flacComplexity = 1974217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL); 1975217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (complexity == null) { 1976217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar complexity = flacComplexity; 1977217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (flacComplexity != null && complexity != flacComplexity) { 1978217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException( 1979217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar "conflicting values for complexity and " + 1980217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar "flac-compression-level"); 1981217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1982217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1983217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1984217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // other audio parameters 1985217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE); 1986217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mime)) { 1987217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE); 1988217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (profile == null) { 1989217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar profile = aacProfile; 1990217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (aacProfile != null && aacProfile != profile) { 1991217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException( 1992217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar "conflicting values for profile and aac-profile"); 1993217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1994217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1995217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1996217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer quality = (Integer)map.get(MediaFormat.KEY_QUALITY); 1997217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1998217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(complexity, quality, profile); 1999b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 200060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber }; 200160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 2002c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main /** 2003c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Encapsulates the profiles available for a codec component. 2004c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <p>You can get a set of {@link MediaCodecInfo.CodecProfileLevel} objects for a given 2005c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * {@link MediaCodecInfo} object from the 2006c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * {@link MediaCodecInfo.CodecCapabilities#profileLevels} field. 2007c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main */ 200860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final class CodecProfileLevel { 200960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_AVCPROFILETYPE 201060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileBaseline = 0x01; 201160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileMain = 0x02; 201260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileExtended = 0x04; 201360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh = 0x08; 201460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh10 = 0x10; 201560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh422 = 0x20; 201660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh444 = 0x40; 201760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 201860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_AVCLEVELTYPE 201960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel1 = 0x01; 202060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel1b = 0x02; 202160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel11 = 0x04; 202260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel12 = 0x08; 202360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel13 = 0x10; 202460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel2 = 0x20; 202560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel21 = 0x40; 202660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel22 = 0x80; 202760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel3 = 0x100; 202860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel31 = 0x200; 202960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel32 = 0x400; 203060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel4 = 0x800; 203160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel41 = 0x1000; 203260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel42 = 0x2000; 203360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel5 = 0x4000; 203460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel51 = 0x8000; 2035b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int AVCLevel52 = 0x10000; 203660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 203760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_H263PROFILETYPE 203860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileBaseline = 0x01; 203960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileH320Coding = 0x02; 204060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileBackwardCompatible = 0x04; 204160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileISWV2 = 0x08; 204260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileISWV3 = 0x10; 204360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileHighCompression = 0x20; 204460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileInternet = 0x40; 204560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileInterlace = 0x80; 204660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileHighLatency = 0x100; 204760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 204860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_H263LEVELTYPE 204960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level10 = 0x01; 205060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level20 = 0x02; 205160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level30 = 0x04; 205260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level40 = 0x08; 205360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level45 = 0x10; 205460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level50 = 0x20; 205560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level60 = 0x40; 205660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level70 = 0x80; 205760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 205860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_MPEG4PROFILETYPE 205960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimple = 0x01; 206060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimpleScalable = 0x02; 206160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileCore = 0x04; 206260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileMain = 0x08; 206360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileNbit = 0x10; 206460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileScalableTexture = 0x20; 206560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimpleFace = 0x40; 206660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimpleFBA = 0x80; 206760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileBasicAnimated = 0x100; 206860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileHybrid = 0x200; 206960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedRealTime = 0x400; 207060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileCoreScalable = 0x800; 207160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedCoding = 0x1000; 207260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedCore = 0x2000; 207360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedScalable = 0x4000; 207460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedSimple = 0x8000; 207560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 207660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_MPEG4LEVELTYPE 207760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level0 = 0x01; 207860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level0b = 0x02; 207960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level1 = 0x04; 208060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level2 = 0x08; 208160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level3 = 0x10; 208260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level4 = 0x20; 208360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level4a = 0x40; 208460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level5 = 0x80; 208560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 208660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_AUDIO_AACPROFILETYPE 208760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectMain = 1; 208860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectLC = 2; 208960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectSSR = 3; 209060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectLTP = 4; 209160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectHE = 5; 209260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectScalable = 6; 209360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectERLC = 17; 209460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectLD = 23; 209560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectHE_PS = 29; 209660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectELD = 39; 209760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 2098e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin // from OMX_VIDEO_VP8LEVELTYPE 2099e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version0 = 0x01; 2100e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version1 = 0x02; 2101e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version2 = 0x04; 2102e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version3 = 0x08; 2103e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin 2104e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin // from OMX_VIDEO_VP8PROFILETYPE 2105e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8ProfileMain = 0x01; 2106e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin 2107aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad // from OMX_VIDEO_HEVCPROFILETYPE 2108aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCProfileMain = 0x01; 2109aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCProfileMain10 = 0x02; 2110aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad 2111aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad // from OMX_VIDEO_HEVCLEVELTYPE 2112aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel1 = 0x1; 2113aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel1 = 0x2; 2114aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel2 = 0x4; 2115aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel2 = 0x8; 2116aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel21 = 0x10; 2117aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel21 = 0x20; 2118aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel3 = 0x40; 2119aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel3 = 0x80; 2120aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel31 = 0x100; 2121aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel31 = 0x200; 2122aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel4 = 0x400; 2123aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel4 = 0x800; 2124aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel41 = 0x1000; 2125aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel41 = 0x2000; 2126aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel5 = 0x4000; 2127aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel5 = 0x8000; 2128aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel51 = 0x10000; 2129aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel51 = 0x20000; 2130aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel52 = 0x40000; 2131aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel52 = 0x80000; 2132aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel6 = 0x100000; 2133aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel6 = 0x200000; 2134aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel61 = 0x400000; 2135aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel61 = 0x800000; 2136aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel62 = 0x1000000; 2137aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel62 = 0x2000000; 2138e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin 213960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 214060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Defined in the OpenMAX IL specs, depending on the type of media 214160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * this can be OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, 2142e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin * OMX_VIDEO_MPEG4PROFILETYPE or OMX_VIDEO_VP8PROFILETYPE. 214360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 214460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public int profile; 214560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 214660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 214760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Defined in the OpenMAX IL specs, depending on the type of media 214860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * this can be OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE 2149e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin * OMX_VIDEO_MPEG4LEVELTYPE or OMX_VIDEO_VP8LEVELTYPE. 215060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 215160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public int level; 215260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber }; 215360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 2154ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber /** 2155ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber * Enumerates the capabilities of the codec component. Since a single 2156ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber * component can support data of a variety of types, the type has to be 2157ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber * specified to yield a meaningful result. 2158c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * @param type The MIME type to query 2159ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber */ 216060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final CodecCapabilities getCapabilitiesForType( 216160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber String type) { 2162b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecCapabilities caps = mCaps.get(type); 2163b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (caps == null) { 2164b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar throw new IllegalArgumentException("codec does not support type"); 2165b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2166b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // clone writable object 2167b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return caps.dup(); 2168b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2169b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2170b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 2171b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public MediaCodecInfo makeRegular() { 2172b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar ArrayList<CodecCapabilities> caps = new ArrayList<CodecCapabilities>(); 2173b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (CodecCapabilities c: mCaps.values()) { 2174b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (c.isRegular()) { 2175b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar caps.add(c); 2176b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2177b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2178b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (caps.size() == 0) { 2179b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return null; 2180b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } else if (caps.size() == mCaps.size()) { 2181b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return this; 2182b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2183b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2184b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return new MediaCodecInfo( 2185b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mName, mIsEncoder, 2186b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar caps.toArray(new CodecCapabilities[caps.size()])); 218760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 218860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber} 2189