160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber/* 260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Copyright (C) 2012 The Android Open Source Project 360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * 460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * you may not use this file except in compliance with the License. 660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * You may obtain a copy of the License at 760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * 860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * http://www.apache.org/licenses/LICENSE-2.0 960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * 1060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Unless required by applicable law or agreed to in writing, software 1160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * See the License for the specific language governing permissions and 1460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * limitations under the License. 1560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 1660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 1760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberpackage android.media; 1860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 1975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wuimport android.annotation.NonNull; 2075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wuimport android.annotation.Nullable; 21b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Log; 22b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Pair; 23b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Range; 24b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Rational; 25b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport android.util.Size; 26b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 27b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.ArrayList; 28b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Arrays; 29b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.HashMap; 30b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Map; 31b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport java.util.Set; 32b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 33b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static android.media.Utils.intersectSortedDistinctRanges; 34b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnarimport static android.media.Utils.sortDistinctRanges; 35b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 36c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main/** 37c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Provides information about a given media codec available on the device. You can 38c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * iterate through all codecs available by querying {@link MediaCodecList}. For example, 39c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * here's how to find an encoder that supports a given MIME type: 40c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <pre> 41c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * private static MediaCodecInfo selectCodec(String mimeType) { 42c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * int numCodecs = MediaCodecList.getCodecCount(); 43c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * for (int i = 0; i < numCodecs; i++) { 44c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * MediaCodecInfo codecInfo = MediaCodecList.getCodecInfoAt(i); 45c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * 46c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * if (!codecInfo.isEncoder()) { 47c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * continue; 48c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 49c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * 50c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * String[] types = codecInfo.getSupportedTypes(); 51c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * for (int j = 0; j < types.length; j++) { 52c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * if (types[j].equalsIgnoreCase(mimeType)) { 53c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * return codecInfo; 54c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 55c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 56c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * } 57c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * return null; 58c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * }</pre> 59c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * 60c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main */ 6160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huberpublic final class MediaCodecInfo { 62b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean mIsEncoder; 63b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private String mName; 64b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private Map<String, CodecCapabilities> mCaps; 6560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 66b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /* package private */ MediaCodecInfo( 67b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String name, boolean isEncoder, CodecCapabilities[] caps) { 68b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mName = name; 69b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mIsEncoder = isEncoder; 70b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mCaps = new HashMap<String, CodecCapabilities>(); 71b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (CodecCapabilities c: caps) { 72217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mCaps.put(c.getMimeType(), c); 73b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 7460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 7560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 7660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 7760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Retrieve the codec name. 7860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 7960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final String getName() { 80b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mName; 8160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 8260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 8360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 8460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Query if the codec is an encoder. 8560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 8660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final boolean isEncoder() { 87b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mIsEncoder; 8860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 8960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 9060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 9160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Query the media types supported by the codec. 9260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 9360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final String[] getSupportedTypes() { 94b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Set<String> typeSet = mCaps.keySet(); 95b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String[] types = typeSet.toArray(new String[typeSet.size()]); 96b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Arrays.sort(types); 97b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return types; 9860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 9960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static int checkPowerOfTwo(int value, String message) { 101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if ((value & (value - 1)) != 0) { 102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException(message); 103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return value; 105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static class Feature { 108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public String mName; 109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int mValue; 110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean mDefault; 111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Feature(String name, int value, boolean def) { 112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mName = name; 113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mValue = value; 114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefault = def; 115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 118217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // COMMON CONSTANTS 119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Integer> POSITIVE_INTEGERS = 120217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(1, Integer.MAX_VALUE); 121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Long> POSITIVE_LONGS = 122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(1l, Long.MAX_VALUE); 123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Rational> POSITIVE_RATIONALS = 124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(new Rational(1, Integer.MAX_VALUE), 125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(Integer.MAX_VALUE, 1)); 126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768); 127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960); 128216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000); 129ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32; 130ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256; 131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // found stuff that is not supported by framework (=> this should not happen) 133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int ERROR_UNRECOGNIZED = (1 << 0); 134217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // found profile/level for which we don't have capability estimates 135217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int ERROR_UNSUPPORTED = (1 << 1); 136217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // have not found any profile/level for which we don't have capability estimate 137217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int ERROR_NONE_SUPPORTED = (1 << 2); 138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 139217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 140ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber /** 141c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Encapsulates the capabilities of a given codec component. 142c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * For example, what profile/level combinations it supports and what colorspaces 14380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * it is capable of providing the decoded data in, as well as some 14480c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * codec-type specific capability flags. 145c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <p>You can get an instance for a given {@link MediaCodecInfo} object with 146c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * {@link MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType()}, passing a MIME type. 147ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber */ 14860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final class CodecCapabilities { 149b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public CodecCapabilities() { 150b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 151b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 152b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // CLASSIFICATION 153b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private String mMime; 154ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu private int mMaxSupportedInstances; 155b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 156b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // LEGACY FIELDS 157b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 158ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // Enumerates supported profile/level combinations as defined 159ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // by the type of encoded data. These combinations impose restrictions 160ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // on video resolution, bitrate... and limit the available encoder tools 161ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber // such as B-frame support, arithmetic coding... 162b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public CodecProfileLevel[] profileLevels; // NOTE this array is modifiable by user 16360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 16460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_COLOR_FORMATTYPE 165e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */ 166b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatMonochrome = 1; 167e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */ 168b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format8bitRGB332 = 2; 169e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */ 170b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format12bitRGB444 = 3; 171e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 172b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitARGB4444 = 4; 173e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 174b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitARGB1555 = 5; 175b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 176b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 177b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 16 bits per pixel RGB color format, with 5-bit red & blue and 6-bit green component. 178b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 179e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Using 16-bit little-endian representation, colors stored as Red 15:11, Green 10:5, Blue 4:0. 180b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <pre> 181b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * byte byte 182b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <--------- i --------> | <------ i + 1 ------> 183b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 184b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * | BLUE | GREEN | RED | 185b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 186b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 0 4 5 7 0 2 3 7 187b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * bit 188b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * </pre> 189e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * 190e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This format corresponds to {@link android.graphics.PixelFormat#RGB_565} and 191e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link android.graphics.ImageFormat#RGB_565}. 192b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 193b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitRGB565 = 6; 194b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_Format16bitRGB565}. */ 195b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format16bitBGR565 = 7; 196e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */ 197b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format18bitRGB666 = 8; 198e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 199b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format18bitARGB1665 = 9; 200e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 201b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format19bitARGB1666 = 10; 202b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 203e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format24bitBGR888} or {@link #COLOR_FormatRGBFlexible}. */ 204e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar public static final int COLOR_Format24bitRGB888 = 11; 205e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar 206b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 207b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 24 bits per pixel RGB color format, with 8-bit red, green & blue components. 208b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 209e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Using 24-bit little-endian representation, colors stored as Red 7:0, Green 15:8, Blue 23:16. 210b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <pre> 211b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * byte byte byte 212b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <------ i -----> | <---- i+1 ----> | <---- i+2 -----> 213b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +-----------------+-----------------+-----------------+ 214e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * | RED | GREEN | BLUE | 215b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +-----------------+-----------------+-----------------+ 216b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * </pre> 217e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * 218e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This format corresponds to {@link android.graphics.PixelFormat#RGB_888}, and can also be 219e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * represented as a flexible format by {@link #COLOR_FormatRGBFlexible}. 220b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 221b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24bitBGR888 = 12; 222e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 223b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24bitARGB1887 = 13; 224e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 225b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format25bitARGB1888 = 14; 226b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 227b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 228e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * @deprecated Use {@link #COLOR_Format32bitABGR8888} Or {@link #COLOR_FormatRGBAFlexible}. 229b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 230b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format32bitBGRA8888 = 15; 231b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 232e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * @deprecated Use {@link #COLOR_Format32bitABGR8888} Or {@link #COLOR_FormatRGBAFlexible}. 233b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 234b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format32bitARGB8888 = 16; 235b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 236b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV411Planar = 17; 237b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 238b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV411PackedPlanar = 18; 239b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 240b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420Planar = 19; 241b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 242b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420PackedPlanar = 20; 243b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 244b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420SemiPlanar = 21; 245b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 246b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 247b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422Planar = 22; 248b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 249b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422PackedPlanar = 23; 250b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 251b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422SemiPlanar = 24; 252b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 253b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 254b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYCbYCr = 25; 255b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 256b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYCrYCb = 26; 257b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 258b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatCbYCrY = 27; 259b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 260b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatCrYCbY = 28; 261b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 262e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV444Flexible}. */ 263b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV444Interleaved = 29; 264b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 265e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 266e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * SMIA 8-bit Bayer format. 267e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Each byte represents the top 8-bits of a 10-bit signal. 268e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 269b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatRawBayer8bit = 30; 270e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 271e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * SMIA 10-bit Bayer format. 272e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 273b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatRawBayer10bit = 31; 274e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar 275e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 276e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * SMIA 8-bit compressed Bayer format. 277e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Each byte represents a sample from the 10-bit signal that is compressed into 8-bits 278e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * using DPCM/PCM compression, as defined by the SMIA Functional Specification. 279e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 280b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatRawBayer8bitcompressed = 32; 281b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 282b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatL8}. */ 283b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL2 = 33; 284b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatL8}. */ 285b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL4 = 34; 286b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 287b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 288b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 8 bits per pixel Y color format. 289b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 290b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * Each byte contains a single pixel. 291e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This format corresponds to {@link android.graphics.PixelFormat#L_8}. 292b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 293b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL8 = 35; 294b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 295b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 296b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 16 bits per pixel, little-endian Y color format. 297b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 298b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <pre> 299b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * byte byte 300b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <--------- i --------> | <------ i + 1 ------> 301b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 302b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * | Y | 303b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ 304b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 0 7 0 7 305b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * bit 306b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * </pre> 307b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 308b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL16 = 36; 309e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_FormatL16}. */ 310b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL24 = 37; 311b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 312b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 313b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 32 bits per pixel, little-endian Y color format. 314b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 315b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <pre> 316b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * byte byte byte byte 317b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 -----> 318b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +-----------------+-----------------+-----------------+-----------------+ 319b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * | Y | 320b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * +-----------------+-----------------+-----------------+-----------------+ 321b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 0 7 0 7 0 7 0 7 322b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * bit 323b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * </pre> 324e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * 325e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * @deprecated Use {@link #COLOR_FormatL16}. 326b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 327b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatL32 = 38; 328b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 329b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 330b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420PackedSemiPlanar = 39; 331b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV422Flexible}. */ 332b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV422PackedSemiPlanar = 40; 333b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 334e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format24bitBGR888}. */ 335b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format18BitBGR666 = 41; 336b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 337e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 338b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24BitARGB6666 = 42; 339e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** @deprecated Use {@link #COLOR_Format32bitABGR8888}. */ 340b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_Format24BitABGR6666 = 43; 341b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 342b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 343b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_TI_FormatYUV420PackedSemiPlanar = 0x7f000100; 34434f17dd1f615c6285f4f344eb700923e2432e48eAndy McFadden // COLOR_FormatSurface indicates that the data will be a GraphicBuffer metadata reference. 34534f17dd1f615c6285f4f344eb700923e2432e48eAndy McFadden // In OMX this is called OMX_COLOR_FormatAndroidOpaque. 346b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatSurface = 0x7F000789; 347b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 348e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 349e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * 32 bits per pixel RGBA color format, with 8-bit red, green, blue, and alpha components. 350e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * <p> 351e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Using 32-bit little-endian representation, colors stored as Red 7:0, Green 15:8, 352e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Blue 23:16, and Alpha 31:24. 353e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * <pre> 354e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * byte byte byte byte 355e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * <------ i -----> | <---- i+1 ----> | <---- i+2 ----> | <---- i+3 -----> 356e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * +-----------------+-----------------+-----------------+-----------------+ 357e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * | RED | GREEN | BLUE | ALPHA | 358e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * +-----------------+-----------------+-----------------+-----------------+ 359e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * </pre> 360e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * 361e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This corresponds to {@link android.graphics.PixelFormat#RGBA_8888}. 362e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 363e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar public static final int COLOR_Format32bitABGR8888 = 0x7F00A000; 364b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 365b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 366b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * Flexible 12 bits per pixel, subsampled YUV color format with 8-bit chroma and luma 367b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * components. 368b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 369b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * Chroma planes are subsampled by 2 both horizontally and vertically. 370b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * Use this format with {@link Image}. 371e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This format corresponds to {@link android.graphics.ImageFormat#YUV_420_888}, 372e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * and can represent the {@link #COLOR_FormatYUV411Planar}, 373e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_FormatYUV411PackedPlanar}, {@link #COLOR_FormatYUV420Planar}, 374e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_FormatYUV420PackedPlanar}, {@link #COLOR_FormatYUV420SemiPlanar} 375e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * and {@link #COLOR_FormatYUV420PackedSemiPlanar} formats. 376b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 377b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * @see Image#getFormat 378b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 379b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_FormatYUV420Flexible = 0x7F420888; 380b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 381b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** 382b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * Flexible 16 bits per pixel, subsampled YUV color format with 8-bit chroma and luma 383b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * components. 384b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * <p> 385e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Chroma planes are horizontally subsampled by 2. Use this format with {@link Image}. 386e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This format corresponds to {@link android.graphics.ImageFormat#YUV_422_888}, 387e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * and can represent the {@link #COLOR_FormatYCbYCr}, {@link #COLOR_FormatYCrYCb}, 388e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_FormatCbYCrY}, {@link #COLOR_FormatCrYCbY}, 389e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_FormatYUV422Planar}, {@link #COLOR_FormatYUV422PackedPlanar}, 390e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_FormatYUV422SemiPlanar} and {@link #COLOR_FormatYUV422PackedSemiPlanar} 391e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * formats. 392b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * 393b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar * @see Image#getFormat 394b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar */ 395b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar public static final int COLOR_FormatYUV422Flexible = 0x7F422888; 396b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar 397e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 398e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Flexible 24 bits per pixel YUV color format with 8-bit chroma and luma 399e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * components. 400e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * <p> 401e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Chroma planes are not subsampled. Use this format with {@link Image}. 402e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * This format corresponds to {@link android.graphics.ImageFormat#YUV_444_888}, 403e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * and can represent the {@link #COLOR_FormatYUV444Interleaved} format. 404e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * @see Image#getFormat 405e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 406e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar public static final int COLOR_FormatYUV444Flexible = 0x7F444888; 407e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar 408e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 409e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Flexible 24 bits per pixel RGB color format with 8-bit red, green and blue 410e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * components. 411e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * <p> 412e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Use this format with {@link Image}. This format corresponds to 413e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link android.graphics.ImageFormat#FLEX_RGB_888}, and can represent 414e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_Format24bitBGR888} and {@link #COLOR_Format24bitRGB888} formats. 415e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * @see Image#getFormat. 416e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 417e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar public static final int COLOR_FormatRGBFlexible = 0x7F36B888; 418e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar 419e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar /** 420e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Flexible 32 bits per pixel RGBA color format with 8-bit red, green, blue, and alpha 421e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * components. 422e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * <p> 423e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * Use this format with {@link Image}. This format corresponds to 424e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link android.graphics.ImageFormat#FLEX_RGBA_8888}, and can represent 425e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_Format32bitBGRA8888}, {@link #COLOR_Format32bitABGR8888} and 426e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * {@link #COLOR_Format32bitARGB8888} formats. 427e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * 428e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar * @see Image#getFormat 429e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar */ 430e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar public static final int COLOR_FormatRGBAFlexible = 0x7F36A888; 431e7f12bfdf69d2f9c5827e385390e12dfdeec3140Lajos Molnar 432b1fa78c132ae97efa8f03c18893c036b8278286cLajos Molnar /** @deprecated Use {@link #COLOR_FormatYUV420Flexible}. */ 433b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int COLOR_QCOM_FormatYUV420SemiPlanar = 0x7fa30c00; 43460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 43560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 43660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Defined in the OpenMAX IL specs, color format values are drawn from 43760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * OMX_COLOR_FORMATTYPE. 43860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 439b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public int[] colorFormats; // NOTE this array is modifiable by user 44080c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar 441b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // FEATURES 442b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 443b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private int mFlagsSupported; 444b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private int mFlagsRequired; 445b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private int mFlagsVerified; 44680c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar 44780c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar /** 44880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * <b>video decoder only</b>: codec supports seamless resolution changes. 44980c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar */ 450b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final String FEATURE_AdaptivePlayback = "adaptive-playback"; 451b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 452b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 453b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <b>video decoder only</b>: codec supports secure decryption. 454b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 455b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final String FEATURE_SecurePlayback = "secure-playback"; 456b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 457b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 458b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <b>video or audio decoder only</b>: codec supports tunneled playback. 459b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 460b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final String FEATURE_TunneledPlayback = "tunneled-playback"; 46180c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar 46280c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar /** 463d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang * <b>video decoder only</b>: codec supports queuing partial frames. 464d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang */ 465d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang public static final String FEATURE_PartialFrame = "partial-frame"; 466d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang 467d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang /** 468e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang * <b>video encoder only</b>: codec supports intra refresh. 469e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang */ 470e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang public static final String FEATURE_IntraRefresh = "intra-refresh"; 471e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang 472e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang /** 47380c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar * Query codec feature capabilities. 474b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <p> 475b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * These features are supported to be used by the codec. These 476b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * include optional features that can be turned on, as well as 477b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * features that are always on. 47880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar */ 47980c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar public final boolean isFeatureSupported(String name) { 480b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return checkFeature(name, mFlagsSupported); 481b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 482b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 483b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 484b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Query codec feature requirements. 485b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * <p> 486b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * These features are required to be used by the codec, and as such, 487b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * they are always turned on. 488b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 489b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public final boolean isFeatureRequired(String name) { 490b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return checkFeature(name, mFlagsRequired); 491b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 492b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 493b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private static final Feature[] decoderFeatures = { 494b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new Feature(FEATURE_AdaptivePlayback, (1 << 0), true), 495b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new Feature(FEATURE_SecurePlayback, (1 << 1), false), 496b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new Feature(FEATURE_TunneledPlayback, (1 << 2), false), 497d5927ae8833780395f8fc5070d0a0a4f8f668292Chong Zhang new Feature(FEATURE_PartialFrame, (1 << 3), false), 498b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar }; 499b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 500e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang private static final Feature[] encoderFeatures = { 501e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang new Feature(FEATURE_IntraRefresh, (1 << 0), false), 502e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang }; 503e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang 504b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 505b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public String[] validFeatures() { 506b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Feature[] features = getValidFeatures(); 507b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String[] res = new String[features.length]; 508b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (int i = 0; i < res.length; i++) { 509b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar res[i] = features[i].mName; 510b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 511b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return res; 512b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 513b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 514b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private Feature[] getValidFeatures() { 515b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (!isEncoder()) { 516b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return decoderFeatures; 517b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 518e9618e810a61fee9b0126fe5dd9741743f6fb332Hangyu Kuang return encoderFeatures; 519b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 520b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 521b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean checkFeature(String name, int flags) { 522b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 523b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (feat.mName.equals(name)) { 524b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return (flags & feat.mValue) != 0; 525b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 52680c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar } 52780c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar return false; 52880c4437ebfe3e679267a64e4c9d7bdd585b7afceLajos Molnar } 529b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 530b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 531b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public boolean isRegular() { 532b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // regular codecs only require default features 533b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 534b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (!feat.mDefault && isFeatureRequired(feat.mName)) { 535b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 536b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 537b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 538b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return true; 539b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 540b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 541b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 542b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Query whether codec supports a given {@link MediaFormat}. 543afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * 544afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * <p class=note> 545afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * <strong>Note:</strong> On {@link android.os.Build.VERSION_CODES#LOLLIPOP}, 546afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * {@code format} must not contain a {@linkplain MediaFormat#KEY_FRAME_RATE 547afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * frame rate}. Use 548afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * <code class=prettyprint>format.setString(MediaFormat.KEY_FRAME_RATE, null)</code> 549afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * to clear any existing frame rate setting in the format. 550db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <p> 551db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * 552db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * The following table summarizes the format keys considered by this method. 553db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * 554db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <table style="width: 0%"> 555db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <thead> 556db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <tr> 557db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <th rowspan=3>OS Version(s)</th> 558db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td colspan=3>{@code MediaFormat} keys considered for</th> 559db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr><tr> 560db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <th>Audio Codecs</th> 561db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <th>Video Codecs</th> 562db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <th>Encoders</th> 563db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr> 564db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </thead> 565db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <tbody> 566db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <tr> 567db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP}</th> 568db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td rowspan=3>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br> 569db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_SAMPLE_RATE},<br> 570db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_CHANNEL_COUNT},</td> 571db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>{@link MediaFormat#KEY_MIME}<sup>*</sup>,<br> 572db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link CodecCapabilities#FEATURE_AdaptivePlayback}<sup>D</sup>,<br> 573db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link CodecCapabilities#FEATURE_SecurePlayback}<sup>D</sup>,<br> 574db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link CodecCapabilities#FEATURE_TunneledPlayback}<sup>D</sup>,<br> 575db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_WIDTH},<br> 576db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_HEIGHT},<br> 577db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <strong>no</strong> {@code KEY_FRAME_RATE}</td> 578db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td rowspan=4>{@link MediaFormat#KEY_BITRATE_MODE},<br> 579db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_PROFILE} 580db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * (and/or {@link MediaFormat#KEY_AAC_PROFILE}<sup>~</sup>),<br> 581db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <!-- {link MediaFormat#KEY_QUALITY},<br> --> 582db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_COMPLEXITY} 583db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * (and/or {@link MediaFormat#KEY_FLAC_COMPRESSION_LEVEL}<sup>~</sup>)</td> 584db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr><tr> 585db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>{@link android.os.Build.VERSION_CODES#LOLLIPOP_MR1}</th> 586db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td rowspan=2>as above, plus<br> 587db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_FRAME_RATE}</td> 588db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr><tr> 589db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>{@link android.os.Build.VERSION_CODES#M}</th> 590db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr><tr> 591db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>{@link android.os.Build.VERSION_CODES#N}</th> 592db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>as above, plus<br> 593db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_PROFILE},<br> 594db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> --> 595db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_BIT_RATE}</td> 596db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td>as above, plus<br> 597db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_PROFILE},<br> 598db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_LEVEL}<sup>+</sup>,<br> 599db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <!-- {link MediaFormat#KEY_MAX_BIT_RATE},<br> --> 600db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link MediaFormat#KEY_BIT_RATE},<br> 601db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * {@link CodecCapabilities#FEATURE_IntraRefresh}<sup>E</sup></td> 602db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr> 603db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <tr> 604db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <td colspan=4> 605db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * <p class=note><strong>Notes:</strong><br> 606db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * *: must be specified; otherwise, method returns {@code false}.<br> 607db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * +: method does not verify that the format parameters are supported 608db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * by the specified level.<br> 609db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * D: decoders only<br> 610db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * E: encoders only<br> 611db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * ~: if both keys are provided values must match 612db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </td> 613db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tr> 614db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </tbody> 615db56549ff24df1f5fc3ff7a816274a69e3fe4c3eLajos Molnar * </table> 616afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * 617b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * @param format media format with optional feature directives. 618b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * @throws IllegalArgumentException if format is not a valid media format. 619b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * @return whether the codec capabilities support the given format 620b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * and feature requests. 621b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 622b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public final boolean isFormatSupported(MediaFormat format) { 623b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar final Map<String, Object> map = format.getMap(); 624b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar final String mime = (String)map.get(MediaFormat.KEY_MIME); 625b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 626b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // mime must match if present 627b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mime != null && !mMime.equalsIgnoreCase(mime)) { 628b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 629b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 630b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 631b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // check feature support 632b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 633b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Integer yesNo = (Integer)map.get(MediaFormat.KEY_FEATURE_ + feat.mName); 634dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar if (yesNo == null) { 635dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar continue; 636dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar } 637b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if ((yesNo == 1 && !isFeatureSupported(feat.mName)) || 638b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar (yesNo == 0 && isFeatureRequired(feat.mName))) { 639b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 640b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 641b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 6420581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 6430581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE); 6440581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar Integer level = (Integer)map.get(MediaFormat.KEY_LEVEL); 6450581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 6460581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (profile != null) { 6470581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (!supportsProfileLevel(profile, level)) { 6480581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return false; 6490581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 6500581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 6510581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // If we recognize this profile, check that this format is supported by the 6520581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // highest level supported by the codec for that profile. (Ignore specified 6530581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // level beyond the above profile/level check as level is only used as a 6540581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1 6550581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile 6560581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // 1080p format is not supported even if codec supports Main Profile Level High, 6570581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // as Simple Profile does not support 1080p. 6580581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar CodecCapabilities levelCaps = null; 6590581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar int maxLevel = 0; 6600581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar for (CodecProfileLevel pl : profileLevels) { 6610581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (pl.profile == profile && pl.level > maxLevel) { 6620581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar maxLevel = pl.level; 6630581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 6640581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 6650581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar levelCaps = createFromProfileLevel(mMime, profile, maxLevel); 66687436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar // remove profile from this format otherwise levelCaps.isFormatSupported will 66787436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar // get into this same conditon and loop forever. 66887436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar Map<String, Object> mapWithoutProfile = new HashMap<>(map); 66987436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar mapWithoutProfile.remove(MediaFormat.KEY_PROFILE); 67087436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile); 67187436bb67fb56e7efa8c475d56a0cc8f97cf79daLajos Molnar if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) { 6720581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return false; 6730581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 6740581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 675b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) { 676b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 677b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 678b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mVideoCaps != null && !mVideoCaps.supportsFormat(format)) { 679b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 680b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 681b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mEncoderCaps != null && !mEncoderCaps.supportsFormat(format)) { 682b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return false; 683b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 684b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return true; 685b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 686b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 6870581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar private static boolean supportsBitrate( 6880581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar Range<Integer> bitrateRange, MediaFormat format) { 6890581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar Map<String, Object> map = format.getMap(); 6900581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 6910581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // consider max bitrate over average bitrate for support 6920581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar Integer maxBitrate = (Integer)map.get(MediaFormat.KEY_MAX_BIT_RATE); 6930581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar Integer bitrate = (Integer)map.get(MediaFormat.KEY_BIT_RATE); 6940581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (bitrate == null) { 6950581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar bitrate = maxBitrate; 6960581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } else if (maxBitrate != null) { 6970581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar bitrate = Math.max(bitrate, maxBitrate); 6980581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 6990581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 7000581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (bitrate != null && bitrate > 0) { 7010581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return bitrateRange.contains(bitrate); 7020581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7030581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 7040581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return true; 7050581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7060581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 7070581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar private boolean supportsProfileLevel(int profile, Integer level) { 7080581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar for (CodecProfileLevel pl: profileLevels) { 7090581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (pl.profile != profile) { 7100581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar continue; 7110581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7120581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 7130581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // AAC does not use levels 7140581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (level == null || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) { 7150581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return true; 7160581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7170581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 7180581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // H.263 levels are not completely ordered: 7190581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // Level45 support only implies Level10 support 7200581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) { 7210581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (pl.level != level && pl.level == CodecProfileLevel.H263Level45 7220581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar && level > CodecProfileLevel.H263Level10) { 7230581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar continue; 7240581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7250581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 7272fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // MPEG4 levels are not completely ordered: 7282fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // Level1 support only implies Level0 (and not Level0b) support 7292fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) { 7302fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (pl.level != level && pl.level == CodecProfileLevel.MPEG4Level1 7312fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar && level > CodecProfileLevel.MPEG4Level0) { 7322fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar continue; 7332fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 7342fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 7352fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 7362fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // HEVC levels incorporate both tiers and levels. Verify tier support. 7372fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) { 7382fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar boolean supportsHighTier = 7392fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar (pl.level & CodecProfileLevel.HEVCHighTierLevels) != 0; 7402fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar boolean checkingHighTier = (level & CodecProfileLevel.HEVCHighTierLevels) != 0; 7412fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // high tier levels are only supported by other high tier levels 7422fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (checkingHighTier && !supportsHighTier) { 7432fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar continue; 7442fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 7452fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 7462fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 7470581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (pl.level >= level) { 7480581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // if we recognize the listed profile/level, we must also recognize the 7490581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // profile/level arguments. 7500581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (createFromProfileLevel(mMime, profile, pl.level) != null) { 7510581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return createFromProfileLevel(mMime, profile, level) != null; 7520581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7530581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return true; 7540581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7550581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7560581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return false; 7570581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 7580581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // errors while reading profile levels - accessed from sister capabilities 760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int mError; 761b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 762b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private static final String TAG = "CodecCapabilities"; 763b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 764b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // NEW-STYLE CAPABILITIES 765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private AudioCapabilities mAudioCaps; 766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private VideoCapabilities mVideoCaps; 767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private EncoderCapabilities mEncoderCaps; 768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private MediaFormat mDefaultFormat; 769b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 770b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 771b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Returns a MediaFormat object with default values for configurations that have 772b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * defaults. 773b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public MediaFormat getDefaultFormat() { 775b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mDefaultFormat; 776b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 777b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 778b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 779b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Returns the mime type for which this codec-capability object was created. 780b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public String getMimeType() { 782b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mMime; 783b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 784b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 785ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu /** 786ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu * Returns the max number of the supported concurrent codec instances. 787ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu * <p> 788ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu * This is a hint for an upper bound. Applications should not expect to successfully 789ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu * operate more instances than the returned value, but the actual number of 790ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu * concurrently operable instances may be less as it depends on the available 791ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu * resources at time of use. 792ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu */ 793ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu public int getMaxSupportedInstances() { 794ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu return mMaxSupportedInstances; 795ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu } 796ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu 797217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean isAudio() { 798217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mAudioCaps != null; 799217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 800217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 801b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the audio capabilities or {@code null} if this is not an audio codec. 803b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public AudioCapabilities getAudioCapabilities() { 805217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mAudioCaps; 806b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 807b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 808b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean isEncoder() { 809b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mEncoderCaps != null; 810b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 811b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 812b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the encoding capabilities or {@code null} if this is not an encoder. 814b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public EncoderCapabilities getEncoderCapabilities() { 816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mEncoderCaps; 817b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 818b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 819b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private boolean isVideo() { 820b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mVideoCaps != null; 821b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 822b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 823b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 824b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Returns the video capabilities or {@code null} if this is not a video codec. 825b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public VideoCapabilities getVideoCapabilities() { 827b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return mVideoCaps; 828b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 829b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public CodecCapabilities dup() { 832217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return new CodecCapabilities( 833217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // clone writable arrays 834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Arrays.copyOf(profileLevels, profileLevels.length), 835217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Arrays.copyOf(colorFormats, colorFormats.length), 836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar isEncoder(), 837217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFlagsVerified, 838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefaultFormat, 839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mCapabilitiesInfo); 840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 842b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 843b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * Retrieve the codec capabilities for a certain {@code mime type}, {@code 844b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * profile} and {@code level}. If the type, or profile-level combination 845b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar * is not understood by the framework, it returns null. 8460d8337c3143867f51a52814830b0dd48535338b7Lajos Molnar * <p class=note> In {@link android.os.Build.VERSION_CODES#M}, calling this 8470d8337c3143867f51a52814830b0dd48535338b7Lajos Molnar * method without calling any method of the {@link MediaCodecList} class beforehand 8480d8337c3143867f51a52814830b0dd48535338b7Lajos Molnar * results in a {@link NullPointerException}.</p> 849b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 850a18b69f5907ef27b9954dfcbe8f60d29fcec2be7Lajos Molnar public static CodecCapabilities createFromProfileLevel( 851b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar String mime, int profile, int level) { 852b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecProfileLevel pl = new CodecProfileLevel(); 853b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar pl.profile = profile; 854b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar pl.level = level; 855b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar MediaFormat defaultFormat = new MediaFormat(); 856b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar defaultFormat.setString(MediaFormat.KEY_MIME, mime); 857b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 858b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecCapabilities ret = new CodecCapabilities( 859b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new CodecProfileLevel[] { pl }, new int[0], true /* encoder */, 860b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 0 /* flags */, defaultFormat, new MediaFormat() /* info */); 861b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (ret.mError != 0) { 862b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return null; 863b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 864b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return ret; 865b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 866b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 867b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /* package private */ CodecCapabilities( 868b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecProfileLevel[] profLevs, int[] colFmts, 869b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar boolean encoder, int flags, 870b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Map<String, Object>defaultFormatMap, 871b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar Map<String, Object>capabilitiesMap) { 872b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar this(profLevs, colFmts, encoder, flags, 873b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new MediaFormat(defaultFormatMap), 874b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar new MediaFormat(capabilitiesMap)); 875b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 876b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 877b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar private MediaFormat mCapabilitiesInfo; 878b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 879b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /* package private */ CodecCapabilities( 880b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecProfileLevel[] profLevs, int[] colFmts, boolean encoder, int flags, 881b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar MediaFormat defaultFormat, MediaFormat info) { 882b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar final Map<String, Object> map = info.getMap(); 883b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar colorFormats = colFmts; 884b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mFlagsVerified = flags; 885b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mDefaultFormat = defaultFormat; 886b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mCapabilitiesInfo = info; 887b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mMime = mDefaultFormat.getString(MediaFormat.KEY_MIME); 888b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 8898acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar /* VP9 introduced profiles around 2016, so some VP9 codecs may not advertise any 8908acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar supported profiles. Determine the level for them using the info they provide. */ 8918acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (profLevs.length == 0 && mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) { 8928acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar CodecProfileLevel profLev = new CodecProfileLevel(); 8938acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar profLev.profile = CodecProfileLevel.VP9Profile0; 8948acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar profLev.level = VideoCapabilities.equivalentVP9Level(info); 8958acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar profLevs = new CodecProfileLevel[] { profLev }; 8968acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar } 8978acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar profileLevels = profLevs; 8988acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 899b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (mMime.toLowerCase().startsWith("audio/")) { 900b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mAudioCaps = AudioCapabilities.create(info, this); 901981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar mAudioCaps.setDefaultFormat(mDefaultFormat); 902b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } else if (mMime.toLowerCase().startsWith("video/")) { 903b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mVideoCaps = VideoCapabilities.create(info, this); 904b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 905b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (encoder) { 906b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mEncoderCaps = EncoderCapabilities.create(info, this); 907981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar mEncoderCaps.setDefaultFormat(mDefaultFormat); 908b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 909b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 910ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu final Map<String, Object> global = MediaCodecList.getGlobalSettings(); 911ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu mMaxSupportedInstances = Utils.parseIntSafely( 91271b5a5866d8ba0eaf45972741b8f1dece36b5d03Ronghua Wu global.get("max-concurrent-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES); 913ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu 914ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu int maxInstances = Utils.parseIntSafely( 91571b5a5866d8ba0eaf45972741b8f1dece36b5d03Ronghua Wu map.get("max-concurrent-instances"), mMaxSupportedInstances); 916ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu mMaxSupportedInstances = 917ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances); 918ee2997577db8d9e3e52593b9ca454386f703d710Ronghua Wu 919b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (Feature feat: getValidFeatures()) { 920981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar String key = MediaFormat.KEY_FEATURE_ + feat.mName; 921981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar Integer yesNo = (Integer)map.get(key); 922b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (yesNo == null) { 923b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar continue; 924dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar } 925dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar if (yesNo > 0) { 926b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mFlagsRequired |= feat.mValue; 927b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 928dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar mFlagsSupported |= feat.mValue; 929dbf1552d526e62859e7a40cfea8e68b614a7d413Lajos Molnar mDefaultFormat.setInteger(key, 1); 930b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // TODO restrict features by mFlagsVerified once all codecs reliably verify them 931b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 932b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 933217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 934b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 935217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 936217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * A class that supports querying the audio capabilities of a codec. 937217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 938217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final class AudioCapabilities { 939217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final String TAG = "AudioCapabilities"; 940217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private CodecCapabilities mParent; 941217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mBitrateRange; 942217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 943217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int[] mSampleRates; 944217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer>[] mSampleRateRanges; 945217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mMaxInputChannelCount; 946217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 947217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final int MAX_INPUT_CHANNEL_COUNT = 30; 948217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 949217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 950217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported bitrates in bits/second. 951217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 952217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getBitrateRange() { 953217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBitrateRange; 954217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 955217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 956217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 957217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the array of supported sample rates if the codec 958217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * supports only discrete values. Otherwise, it returns 959217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code null}. The array is sorted in ascending order. 960217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 961217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int[] getSupportedSampleRates() { 962217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return Arrays.copyOf(mSampleRates, mSampleRates.length); 963217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 964217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 965217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 966217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the array of supported sample rate ranges. The 967217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * array is sorted in ascending order, and the ranges are 968217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * distinct. 969217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 970217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer>[] getSupportedSampleRateRanges() { 971217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return Arrays.copyOf(mSampleRateRanges, mSampleRateRanges.length); 972217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 973217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 974217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 975217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the maximum number of input channels supported. The codec 976217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * supports any number of channels between 1 and this maximum value. 977217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 978217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getMaxInputChannelCount() { 979217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mMaxInputChannelCount; 980217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 981b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 982217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* no public constructor */ 983217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private AudioCapabilities() { } 984217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 985217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 986217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static AudioCapabilities create( 987217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MediaFormat info, CodecCapabilities parent) { 988217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar AudioCapabilities caps = new AudioCapabilities(); 989217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar caps.init(info, parent); 990217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return caps; 991217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 992217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 993217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 994217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void init(MediaFormat info, CodecCapabilities parent) { 995217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent = parent; 996217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar initWithPlatformLimits(); 997217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLevelLimits(); 998217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar parseFromInfo(info); 999217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1000217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1001217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void initWithPlatformLimits() { 1002217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitrateRange = Range.create(0, Integer.MAX_VALUE); 1003217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mMaxInputChannelCount = MAX_INPUT_CHANNEL_COUNT; 1004217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // mBitrateRange = Range.create(1, 320000); 1005217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges = new Range[] { Range.create(8000, 96000) }; 1006217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates = null; 1007217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1008217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1009217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean supports(Integer sampleRate, Integer inputChannels) { 1010217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // channels and sample rates are checked orthogonally 1011217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (inputChannels != null && 1012217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (inputChannels < 1 || inputChannels > mMaxInputChannelCount)) { 1013217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 1014b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1015217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (sampleRate != null) { 1016217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int ix = Utils.binarySearchDistinctRanges( 1017217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges, sampleRate); 1018217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ix < 0) { 1019217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 1020217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1021217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1022217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return true; 1023217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1024b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1025217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1026217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Query whether the sample rate is supported by the codec. 1027217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1028217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean isSampleRateSupported(int sampleRate) { 1029217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(sampleRate, null); 1030217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1031217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1032217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** modifies rates */ 1033217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void limitSampleRates(int[] rates) { 1034217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Arrays.sort(rates); 1035217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ArrayList<Range<Integer>> ranges = new ArrayList<Range<Integer>>(); 1036217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (int rate: rates) { 1037217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (supports(rate, null /* channels */)) { 1038217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ranges.add(Range.create(rate, rate)); 1039217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1040b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1041217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges = ranges.toArray(new Range[ranges.size()]); 1042217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar createDiscreteSampleRates(); 1043217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1044b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1045217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void createDiscreteSampleRates() { 1046217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates = new int[mSampleRateRanges.length]; 1047217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (int i = 0; i < mSampleRateRanges.length; i++) { 1048217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates[i] = mSampleRateRanges[i].getLower(); 1049217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1050217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1051b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1052217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** modifies rateRanges */ 1053217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void limitSampleRates(Range<Integer>[] rateRanges) { 1054217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sortDistinctRanges(rateRanges); 1055217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRateRanges = intersectSortedDistinctRanges(mSampleRateRanges, rateRanges); 1056217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1057217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // check if all values are discrete 1058217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Range<Integer> range: mSampleRateRanges) { 1059217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!range.getLower().equals(range.getUpper())) { 1060217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSampleRates = null; 1061217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return; 1062217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1063b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1064217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar createDiscreteSampleRates(); 1065217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1066217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1067217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLevelLimits() { 1068217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int[] sampleRates = null; 1069217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> sampleRateRange = null, bitRates = null; 1070f31d11341e689ff5a630350cb48d30ff0ec21e70Robert Shih int maxChannels = MAX_INPUT_CHANNEL_COUNT; 1071217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String mime = mParent.getMimeType(); 1072217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1073217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MPEG)) { 1074217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 1075217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 8000, 11025, 12000, 1076217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16000, 22050, 24000, 1077217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 32000, 44100, 48000 }; 1078217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(8000, 320000); 1079217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 2; 1080217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB)) { 1081217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000 }; 1082217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(4750, 12200); 1083217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 1; 1084217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB)) { 1085217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 16000 }; 1086217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(6600, 23850); 1087217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 1; 1088217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) { 1089217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 1090217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 7350, 8000, 1091217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 11025, 12000, 16000, 1092217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 22050, 24000, 32000, 1093217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 44100, 48000, 64000, 1094217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 88200, 96000 }; 1095217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(8000, 510000); 1096217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 48; 1097217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_VORBIS)) { 1098217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(32000, 500000); 1099610e288de6727d9be3277777e6c5abca4b18aa86Lajos Molnar sampleRateRange = Range.create(8000, 192000); 1100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 255; 1101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_OPUS)) { 1102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(6000, 510000); 1103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000, 12000, 16000, 24000, 48000 }; 1104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 255; 1105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_RAW)) { 1106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRateRange = Range.create(1, 96000); 1107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(1, 10000000); 1108bd2c3d65d6b62b5a359268246e7ebe96904bd851Glenn Kasten maxChannels = AudioTrack.CHANNEL_COUNT_MAX; 1109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) { 1110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRateRange = Range.create(1, 655350); 1111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // lossless codec, so bitrate is ignored 1112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 255; 1113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW) 1114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW)) { 1115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000 }; 1116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(64000, 64000); 1117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // platform allows multiple channels for this format 1118217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) { 1119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar sampleRates = new int[] { 8000 }; 1120217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = Range.create(13000, 13000); 1121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxChannels = 1; 1122b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AC3)) { 1123b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen maxChannels = 6; 1124b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_EAC3)) { 1125b95d7b5af42107d022d4f450d96563134895cf87ZhiWei Chen maxChannels = 16; 1126217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else { 1127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unsupported mime " + mime); 1128217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent.mError |= ERROR_UNSUPPORTED; 1129217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1130217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // restrict ranges 1132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (sampleRates != null) { 1133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar limitSampleRates(sampleRates); 1134217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (sampleRateRange != null) { 1135217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar limitSampleRates(new Range[] { sampleRateRange }); 1136217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1137217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLimits(maxChannels, bitRates); 1138217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1139b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1140217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLimits(int maxInputChannels, Range<Integer> bitRates) { 1141217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mMaxInputChannelCount = Range.create(1, mMaxInputChannelCount) 1142217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar .clamp(maxInputChannels); 1143217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (bitRates != null) { 1144217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitrateRange = mBitrateRange.intersect(bitRates); 1145b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1146217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1147217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1148217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void parseFromInfo(MediaFormat info) { 1149217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxInputChannels = MAX_INPUT_CHANNEL_COUNT; 1150217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> bitRates = POSITIVE_INTEGERS; 1151b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1152217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("sample-rate-ranges")) { 1153217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String[] rateStrings = info.getString("sample-rate-ranges").split(","); 1154217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer>[] rateRanges = new Range[rateStrings.length]; 1155217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (int i = 0; i < rateStrings.length; i++) { 1156217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar rateRanges[i] = Utils.parseIntRange(rateStrings[i], null); 1157217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1158217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar limitSampleRates(rateRanges); 1159217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1160217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("max-channel-count")) { 1161217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxInputChannels = Utils.parseIntSafely( 1162217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar info.getString("max-channel-count"), maxInputChannels); 1163f31d11341e689ff5a630350cb48d30ff0ec21e70Robert Shih } else if ((mParent.mError & ERROR_UNSUPPORTED) != 0) { 1164f31d11341e689ff5a630350cb48d30ff0ec21e70Robert Shih maxInputChannels = 0; 1165217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1166217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("bitrate-range")) { 1167217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar bitRates = bitRates.intersect( 1168216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang Utils.parseIntRange(info.getString("bitrate-range"), bitRates)); 1169b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1170217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLimits(maxInputChannels, bitRates); 1171217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1172b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1173217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1174217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void setDefaultFormat(MediaFormat format) { 1175217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // report settings that have only a single choice 1176217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mBitrateRange.getLower().equals(mBitrateRange.getUpper())) { 1177217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_BIT_RATE, mBitrateRange.getLower()); 1178217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1179217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mMaxInputChannelCount == 1) { 1180217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // mono-only format 1181217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_CHANNEL_COUNT, 1); 1182217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1183217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mSampleRates != null && mSampleRates.length == 1) { 1184217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_SAMPLE_RATE, mSampleRates[0]); 1185217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1186217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1187217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1188217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1189217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean supportsFormat(MediaFormat format) { 1190217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Map<String, Object> map = format.getMap(); 1191217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE); 1192217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT); 11930581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 1194217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!supports(sampleRate, channels)) { 1195217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 1196217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1197217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 11980581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) { 11990581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return false; 12000581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 12010581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 1202217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // nothing to do for: 1203217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // KEY_CHANNEL_MASK: codecs don't get this 1204217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // KEY_IS_ADTS: required feature for all AAC decoders 1205217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return true; 1206217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1207217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1208217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1209217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1210217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * A class that supports querying the video capabilities of a codec. 1211217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1212217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final class VideoCapabilities { 1213217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final String TAG = "VideoCapabilities"; 1214217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private CodecCapabilities mParent; 1215217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mBitrateRange; 1216217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1217217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mHeightRange; 1218217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mWidthRange; 1219217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mBlockCountRange; 1220217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mHorizontalBlockRange; 1221217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mVerticalBlockRange; 1222217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Rational> mAspectRatioRange; 1223217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Rational> mBlockAspectRatioRange; 1224217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Long> mBlocksPerSecondRange; 122575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu private Map<Size, Range<Long>> mMeasuredFrameRates; 1226217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mFrameRateRange; 1227217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1228217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mBlockWidth; 1229217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mBlockHeight; 1230217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mWidthAlignment; 1231217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mHeightAlignment; 1232217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mSmallerDimensionUpperLimit; 1233217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 12342fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar private boolean mAllowMbOverride; // allow XML to override calculated limits 12352fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 1236217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1237217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported bitrates in bits/second. 1238217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1239217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getBitrateRange() { 1240217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBitrateRange; 1241217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1242217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1243217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1244217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video widths. 1245217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1246217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedWidths() { 1247217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mWidthRange; 1248217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1249217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1250217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1251217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video heights. 1252217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1253217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedHeights() { 1254217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mHeightRange; 1255217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1256217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1257217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1258217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the alignment requirement for video width (in pixels). 1259217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 1260217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is a power-of-2 value that video width must be a 1261217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * multiple of. 1262217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1263217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getWidthAlignment() { 1264217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mWidthAlignment; 1265217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1266217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1267217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1268217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the alignment requirement for video height (in pixels). 1269217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 1270217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is a power-of-2 value that video height must be a 1271217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * multiple of. 1272217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1273217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getHeightAlignment() { 1274217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mHeightAlignment; 1275217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1276217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1277217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1278217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Return the upper limit on the smaller dimension of width or height. 1279217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p></p> 1280217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Some codecs have a limit on the smaller dimension, whether it be 1281217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * the width or the height. E.g. a codec may only be able to handle 1282217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * up to 1920x1080 both in landscape and portrait mode (1080x1920). 1283217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * In this case the maximum width and height are both 1920, but the 1284217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * smaller dimension limit will be 1080. For other codecs, this is 1285217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code Math.min(getSupportedWidths().getUpper(), 1286217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * getSupportedHeights().getUpper())}. 1287217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 1288217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @hide 1289217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1290217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public int getSmallerDimensionUpperLimit() { 1291217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mSmallerDimensionUpperLimit; 1292217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1293217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1294217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1295217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported frame rates. 1296217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p> 1297217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is not a performance indicator. Rather, it expresses the 1298217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * limits specified in the coding standard, based on the complexities 1299217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * of encoding material for later playback at a certain frame rate, 1300217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * or the decoding of such material in non-realtime. 1301217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1302217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedFrameRates() { 1303217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mFrameRateRange; 1304217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1305217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1306217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1307217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video widths for a video height. 1308217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param height the height of the video 1309217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1310217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedWidthsFor(int height) { 1311217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1312217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> range = mWidthRange; 1313217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mHeightRange.contains(height) 1314217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || (height % mHeightAlignment) != 0) { 1315217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported height"); 1316b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1317217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int heightInBlocks = Utils.divUp(height, mBlockHeight); 1318217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1319217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by block count and by block aspect ratio 1320217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int minWidthInBlocks = Math.max( 1321217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.divUp(mBlockCountRange.getLower(), heightInBlocks), 1322217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(mBlockAspectRatioRange.getLower().doubleValue() 1323217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * heightInBlocks)); 1324217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int maxWidthInBlocks = Math.min( 1325217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / heightInBlocks, 1326217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mBlockAspectRatioRange.getUpper().doubleValue() 1327217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * heightInBlocks)); 1328217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 1329217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (minWidthInBlocks - 1) * mBlockWidth + mWidthAlignment, 1330217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxWidthInBlocks * mBlockWidth); 1331217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1332217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by smaller dimension limit 1333217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (height > mSmallerDimensionUpperLimit) { 1334217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect(1, mSmallerDimensionUpperLimit); 1335b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1336b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1337217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by aspect ratio 1338217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 1339217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(mAspectRatioRange.getLower().doubleValue() 1340217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * height), 1341217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mAspectRatioRange.getUpper().doubleValue() * height)); 1342217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return range; 1343217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 13446c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar // height is not supported because there are no suitable widths 13456c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar Log.v(TAG, "could not get supported widths for " + height); 1346217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported height"); 1347b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1348217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1349b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1350217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1351217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video heights for a video width 1352217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param width the width of the video 1353217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1354217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getSupportedHeightsFor(int width) { 1355217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1356217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> range = mHeightRange; 1357217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mWidthRange.contains(width) 1358217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || (width % mWidthAlignment) != 0) { 1359217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported width"); 1360b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1361217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int widthInBlocks = Utils.divUp(width, mBlockWidth); 1362217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1363217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by block count and by block aspect ratio 1364217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int minHeightInBlocks = Math.max( 1365217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.divUp(mBlockCountRange.getLower(), widthInBlocks), 1366217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(widthInBlocks / 1367217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange.getUpper().doubleValue())); 1368217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int maxHeightInBlocks = Math.min( 1369217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / widthInBlocks, 1370217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(widthInBlocks / 1371217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange.getLower().doubleValue())); 1372217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 1373217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (minHeightInBlocks - 1) * mBlockHeight + mHeightAlignment, 1374217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxHeightInBlocks * mBlockHeight); 1375217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1376217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by smaller dimension limit 1377217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (width > mSmallerDimensionUpperLimit) { 1378217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect(1, mSmallerDimensionUpperLimit); 1379217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1380217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1381217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // constrain by aspect ratio 1382217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar range = range.intersect( 1383217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)Math.ceil(width / 1384217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange.getUpper().doubleValue()), 1385217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(width / mAspectRatioRange.getLower().doubleValue())); 1386217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return range; 1387217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 13886c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar // width is not supported because there are no suitable heights 13896c9833b9674197eb3ef3d1617584787600f5e7dfLajos Molnar Log.v(TAG, "could not get supported heights for " + width); 1390217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported width"); 1391217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1392217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1393217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1394217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1395217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the range of supported video frame rates for a video size. 1396217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p> 1397217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * This is not a performance indicator. Rather, it expresses the limits specified in 1398217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * the coding standard, based on the complexities of encoding material of a given 1399217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * size for later playback at a certain frame rate, or the decoding of such material 1400217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * in non-realtime. 1401217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1402217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param width the width of the video 1403217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @param height the height of the video 1404217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1405217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Double> getSupportedFrameRatesFor(int width, int height) { 1406217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> range = mHeightRange; 1407217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!supports(width, height, null)) { 1408217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException("unsupported size"); 1409217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1410217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int blockCount = 1411217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight); 1412217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1413217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return Range.create( 1414217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.max(mBlocksPerSecondRange.getLower() / (double) blockCount, 1415217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (double) mFrameRateRange.getLower()), 1416217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(mBlocksPerSecondRange.getUpper() / (double) blockCount, 1417217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (double) mFrameRateRange.getUpper())); 1418217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1419217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1420e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu private int getBlockCount(int width, int height) { 1421e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu return Utils.divUp(width, mBlockWidth) * Utils.divUp(height, mBlockHeight); 1422e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu } 1423e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu 142475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu @NonNull 142575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu private Size findClosestSize(int width, int height) { 1426e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu int targetBlockCount = getBlockCount(width, height); 142775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Size closestSize = null; 1428e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu int minDiff = Integer.MAX_VALUE; 142975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu for (Size size : mMeasuredFrameRates.keySet()) { 1430e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu int diff = Math.abs(targetBlockCount - 1431e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu getBlockCount(size.getWidth(), size.getHeight())); 1432e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu if (diff < minDiff) { 1433e595268e98ee609899c71c4114fc098daa2ee1f4Ronghua Wu minDiff = diff; 143475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu closestSize = size; 143575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 143675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 143775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu return closestSize; 143875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 143975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu 144075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu private Range<Double> estimateFrameRatesFor(int width, int height) { 144175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Size size = findClosestSize(width, height); 144275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Range<Long> range = mMeasuredFrameRates.get(size); 14437a2ab16b65f7ae252a7b127a7286f6ecde87bdf0Lajos Molnar Double ratio = getBlockCount(size.getWidth(), size.getHeight()) 14447a2ab16b65f7ae252a7b127a7286f6ecde87bdf0Lajos Molnar / (double)Math.max(getBlockCount(width, height), 1); 144575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu return Range.create(range.getLower() * ratio, range.getUpper() * ratio); 144675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 144775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu 1448217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 144938a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * Returns the range of achievable video frame rates for a video size. 145038a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * May return {@code null}, if the codec did not publish any measurement 145138a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * data. 145238a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * <p> 1453b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * This is a performance estimate provided by the device manufacturer based on statistical 1454b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * sampling of full-speed decoding and encoding measurements in various configurations 1455afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * of common video sizes supported by the codec. As such it should only be used to 1456afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * compare individual codecs on the device. The value is not suitable for comparing 1457afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * different devices or even different android releases for the same device. 1458afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * <p> 1459b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * <em>On {@link android.os.Build.VERSION_CODES#M} release</em> the returned range 1460b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * corresponds to the fastest frame rates achieved in the tested configurations. As 1461b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * such, it should not be used to gauge guaranteed or even average codec performance 1462b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * on the device. 1463b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * <p> 1464b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * <em>On {@link android.os.Build.VERSION_CODES#N} release</em> the returned range 1465b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * corresponds closer to sustained performance <em>in tested configurations</em>. 1466b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * One can expect to achieve sustained performance higher than the lower limit more than 1467b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * 50% of the time, and higher than half of the lower limit at least 90% of the time 1468b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * <em>in tested configurations</em>. 1469b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * Conversely, one can expect performance lower than twice the upper limit at least 1470b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * 90% of the time. 1471b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * <p class=note> 1472b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * Tested configurations use a single active codec. For use cases where multiple 1473b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * codecs are active, applications can expect lower and in most cases significantly lower 1474b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * performance. 1475b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * <p class=note> 1476b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * The returned range value is interpolated from the nearest frame size(s) tested. 1477b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * Codec performance is severely impacted by other activity on the device as well 1478b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * as environmental factors (such as battery level, temperature or power source), and can 1479b28b99a4257f2ef6d747cc8dc4d60a23cc69e0ebLajos Molnar * vary significantly even in a steady environment. 1480afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * <p class=note> 1481afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * Use this method in cases where only codec performance matters, e.g. to evaluate if 1482afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * a codec has any chance of meeting a performance target. Codecs are listed 1483afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * in {@link MediaCodecList} in the preferred order as defined by the device 1484afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * manufacturer. As such, applications should use the first suitable codec in the 1485afa6ceb5a0d809b630db43564d3ce7f7b821129cLajos Molnar * list to achieve the best balance between power use and performance. 148638a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * 148738a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * @param width the width of the video 148838a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * @param height the height of the video 148938a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * 149038a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar * @throws IllegalArgumentException if the video size is not supported. 149138a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar */ 149275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu @Nullable 149338a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar public Range<Double> getAchievableFrameRatesFor(int width, int height) { 149438a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar if (!supports(width, height, null)) { 149538a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar throw new IllegalArgumentException("unsupported size"); 149638a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar } 149775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu 149875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu if (mMeasuredFrameRates == null || mMeasuredFrameRates.size() <= 0) { 149975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Log.w(TAG, "Codec did not publish any measurement data."); 150075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu return null; 150175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 150275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu 150375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu return estimateFrameRatesFor(width, height); 150438a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar } 150538a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar 150638a296a65f89b0b16a717fe29f583db21e5c46dfLajos Molnar /** 1507217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns whether a given video size ({@code width} and 1508217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code height}) and {@code frameRate} combination is supported. 1509217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1510217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean areSizeAndRateSupported( 1511217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int width, int height, double frameRate) { 1512217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(width, height, frameRate); 1513217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1514217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1515217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1516217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns whether a given video size ({@code width} and 1517217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * {@code height}) is supported. 1518217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 1519217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean isSizeSupported(int width, int height) { 1520217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(width, height, null); 1521217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1522217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 15230581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar private boolean supports(Integer width, Integer height, Number rate) { 1524217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean ok = true; 1525217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1526217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && width != null) { 1527217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mWidthRange.contains(width) 1528217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && (width % mWidthAlignment == 0); 1529217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1530217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && height != null) { 1531217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mHeightRange.contains(height) 1532217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && (height % mHeightAlignment == 0); 1533b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1534217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && rate != null) { 1535a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar ok = mFrameRateRange.contains(Utils.intRangeFor(rate.doubleValue())); 1536217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1537217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && height != null && width != null) { 1538217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = Math.min(height, width) <= mSmallerDimensionUpperLimit; 1539b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1540217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int widthInBlocks = Utils.divUp(width, mBlockWidth); 1541217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int heightInBlocks = Utils.divUp(height, mBlockHeight); 1542217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int blockCount = widthInBlocks * heightInBlocks; 1543217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = ok && mBlockCountRange.contains(blockCount) 1544217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mBlockAspectRatioRange.contains( 1545217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(widthInBlocks, heightInBlocks)) 1546217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mAspectRatioRange.contains(new Rational(width, height)); 1547217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && rate != null) { 1548a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar double blocksPerSec = blockCount * rate.doubleValue(); 1549217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mBlocksPerSecondRange.contains( 1550217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.longRangeFor(blocksPerSec)); 1551b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1552b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1553217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return ok; 1554217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1555b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1556217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 1557217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @hide 1558217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @throws java.lang.ClassCastException */ 1559217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean supportsFormat(MediaFormat format) { 1560217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final Map<String, Object> map = format.getMap(); 1561217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer width = (Integer)map.get(MediaFormat.KEY_WIDTH); 1562217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT); 1563a4fcb62a224eca99d53b1692d1cc5ae5ff2d2127Lajos Molnar Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE); 1564217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 15650581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (!supports(width, height, rate)) { 15660581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return false; 15670581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 1568217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 15690581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) { 15700581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return false; 15710581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar } 15720581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar 15730581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar // we ignore color-format for now as it is not reliably reported by codec 15740581ee49719fba54fc37071ffa357f4518cf1583Lajos Molnar return true; 1575217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1576217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1577217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* no public constructor */ 1578217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private VideoCapabilities() { } 1579217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1580217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1581217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static VideoCapabilities create( 1582217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MediaFormat info, CodecCapabilities parent) { 1583217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar VideoCapabilities caps = new VideoCapabilities(); 1584217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar caps.init(info, parent); 1585217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return caps; 1586217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1587217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1588217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1589217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void init(MediaFormat info, CodecCapabilities parent) { 1590217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent = parent; 1591217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar initWithPlatformLimits(); 1592217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLevelLimits(); 1593217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar parseFromInfo(info); 1594217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar updateLimits(); 1595217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1596217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1597217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1598217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Size getBlockSize() { 1599217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return new Size(mBlockWidth, mBlockHeight); 1600217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1601217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1602217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1603217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getBlockCountRange() { 1604217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBlockCountRange; 1605217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1606217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1607217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1608217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Long> getBlocksPerSecondRange() { 1609217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mBlocksPerSecondRange; 1610217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1611b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1612217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 1613217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Rational> getAspectRatioRange(boolean blocks) { 1614217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return blocks ? mBlockAspectRatioRange : mAspectRatioRange; 1615217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1616217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1617217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void initWithPlatformLimits() { 1618216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang mBitrateRange = BITRATE_RANGE; 1619217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1620217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = SIZE_RANGE; 1621217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = SIZE_RANGE; 1622217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = FRAME_RATE_RANGE; 1623217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1624217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = SIZE_RANGE; 1625217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = SIZE_RANGE; 1626217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1627217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // full positive ranges are supported as these get calculated 1628217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = POSITIVE_INTEGERS; 1629217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = POSITIVE_LONGS; 1630217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1631217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = POSITIVE_RATIONALS; 1632217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = POSITIVE_RATIONALS; 1633217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1634217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // YUV 4:2:0 requires 2:2 alignment 1635217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthAlignment = 2; 1636217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightAlignment = 2; 1637217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth = 2; 1638217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight = 2; 1639217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = SIZE_RANGE.getUpper(); 1640217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1641217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 164275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu private Map<Size, Range<Long>> getMeasuredFrameRates(Map<String, Object> map) { 164375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Map<Size, Range<Long>> ret = new HashMap<Size, Range<Long>>(); 164475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu final String prefix = "measured-frame-rate-"; 164575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Set<String> keys = map.keySet(); 164675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu for (String key : keys) { 164775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu // looking for: measured-frame-rate-WIDTHxHEIGHT-range 164875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu if (!key.startsWith(prefix)) { 164975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu continue; 165075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 165175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu String subKey = key.substring(prefix.length()); 165275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu String[] temp = key.split("-"); 165375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu if (temp.length != 5) { 165475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu continue; 165575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 165675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu String sizeStr = temp[3]; 165775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Size size = Utils.parseSize(sizeStr, null); 165875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu if (size == null || size.getWidth() * size.getHeight() <= 0) { 165975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu continue; 166075c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 166175c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu Range<Long> range = Utils.parseLongRange(map.get(key), null); 166275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu if (range == null || range.getLower() < 0 || range.getUpper() < 0) { 166375c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu continue; 166475c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 166575c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu ret.put(size, range); 166675c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 166775c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu return ret; 166875c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu } 166975c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu 16708acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar private static Pair<Range<Integer>, Range<Integer>> parseWidthHeightRanges(Object o) { 16718acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Pair<Size, Size> range = Utils.parseSizeRange(o); 16728acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (range != null) { 16738acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar try { 16748acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return Pair.create( 16758acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Range.create(range.first.getWidth(), range.second.getWidth()), 16768acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Range.create(range.first.getHeight(), range.second.getHeight())); 16778acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar } catch (IllegalArgumentException e) { 16788acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Log.w(TAG, "could not parse size range '" + o + "'"); 16798acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar } 16808acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar } 16818acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return null; 16828acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar } 16838acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 16848acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar /** @hide */ 16858acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar public static int equivalentVP9Level(MediaFormat info) { 16868acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar final Map<String, Object> map = info.getMap(); 16878acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 16888acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Size blockSize = Utils.parseSize(map.get("block-size"), new Size(8, 8)); 16898acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int BS = blockSize.getWidth() * blockSize.getHeight(); 16908acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 16918acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Range<Integer> counts = Utils.parseIntRange(map.get("block-count-range"), null); 16928acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int FS = counts == null ? 0 : BS * counts.getUpper(); 16938acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 16948acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Range<Long> blockRates = 16958acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Utils.parseLongRange(map.get("blocks-per-second-range"), null); 16968acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar long SR = blockRates == null ? 0 : BS * blockRates.getUpper(); 16978acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 16988acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Pair<Range<Integer>, Range<Integer>> dimensionRanges = 16998acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar parseWidthHeightRanges(map.get("size-range")); 17008acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int D = dimensionRanges == null ? 0 : Math.max( 17018acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar dimensionRanges.first.getUpper(), dimensionRanges.second.getUpper()); 17028acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 17038acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Range<Integer> bitRates = Utils.parseIntRange(map.get("bitrate-range"), null); 17048acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int BR = bitRates == null ? 0 : Utils.divUp(bitRates.getUpper(), 1000); 17058acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 17068acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 829440 && FS <= 36864 && BR <= 200 && D <= 512) 17078acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level1; 17088acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 2764800 && FS <= 73728 && BR <= 800 && D <= 768) 17098acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level11; 17108acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 4608000 && FS <= 122880 && BR <= 1800 && D <= 960) 17118acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level2; 17128acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 9216000 && FS <= 245760 && BR <= 3600 && D <= 1344) 17138acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level21; 17148acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 20736000 && FS <= 552960 && BR <= 7200 && D <= 2048) 17158acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level3; 17168acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 36864000 && FS <= 983040 && BR <= 12000 && D <= 2752) 17178acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level31; 17188acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 83558400 && FS <= 2228224 && BR <= 18000 && D <= 4160) 17198acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level4; 17208acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 160432128 && FS <= 2228224 && BR <= 30000 && D <= 4160) 17218acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level41; 17228acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 311951360 && FS <= 8912896 && BR <= 60000 && D <= 8384) 17238acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level5; 17248acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 588251136 && FS <= 8912896 && BR <= 120000 && D <= 8384) 17258acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level51; 17268acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 1176502272 && FS <= 8912896 && BR <= 180000 && D <= 8384) 17278acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level52; 17288acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 1176502272 && FS <= 35651584 && BR <= 180000 && D <= 16832) 17298acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level6; 17308acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 2353004544L && FS <= 35651584 && BR <= 240000 && D <= 16832) 17318acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level61; 17328acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (SR <= 4706009088L && FS <= 35651584 && BR <= 480000 && D <= 16832) 17338acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level62; 17348acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar // returning largest level 17358acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar return CodecProfileLevel.VP9Level62; 17368acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar } 17378acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar 1738217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void parseFromInfo(MediaFormat info) { 1739217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final Map<String, Object> map = info.getMap(); 1740217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Size blockSize = new Size(mBlockWidth, mBlockHeight); 1741217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Size alignment = new Size(mWidthAlignment, mHeightAlignment); 1742217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> counts = null, widths = null, heights = null; 1743216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang Range<Integer> frameRates = null, bitRates = null; 1744217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Long> blockRates = null; 1745217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Rational> ratios = null, blockRatios = null; 1746217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1747217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockSize = Utils.parseSize(map.get("block-size"), blockSize); 1748217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment = Utils.parseSize(map.get("alignment"), alignment); 1749217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar counts = Utils.parseIntRange(map.get("block-count-range"), null); 1750217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockRates = 1751217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.parseLongRange(map.get("blocks-per-second-range"), null); 175275c4824bf6efd996956edb4436f2d85bad4ac473Ronghua Wu mMeasuredFrameRates = getMeasuredFrameRates(map); 17538acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar Pair<Range<Integer>, Range<Integer>> sizeRanges = 17548acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar parseWidthHeightRanges(map.get("size-range")); 17558acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar if (sizeRanges != null) { 17568acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar widths = sizeRanges.first; 17578acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar heights = sizeRanges.second; 1758b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // for now this just means using the smaller max size as 2nd 1760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // upper limit. 1761217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // for now we are keeping the profile specific "width/height 1762217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // in macroblocks" limits. 17631c436bd911373810b2ac14088dd16762daf94191Lajos Molnar if (map.containsKey("feature-can-swap-width-height")) { 1764217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widths != null) { 1765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = 1766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(widths.getUpper(), heights.getUpper()); 1767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar widths = heights = widths.extend(heights); 1768981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } else { 1769217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "feature can-swap-width-height is best used with size-range"); 1770217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = 1771217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(mWidthRange.getUpper(), mHeightRange.getUpper()); 1772217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = mHeightRange = mWidthRange.extend(mHeightRange); 1773b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1774b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1775b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1776217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ratios = Utils.parseRationalRange( 1777217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar map.get("block-aspect-ratio-range"), null); 1778217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockRatios = Utils.parseRationalRange( 1779217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar map.get("pixel-aspect-ratio-range"), null); 1780217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar frameRates = Utils.parseIntRange(map.get("frame-rate-range"), null); 1781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (frameRates != null) { 1782217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 1783217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar frameRates = frameRates.intersect(FRAME_RATE_RANGE); 1784217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (IllegalArgumentException e) { 1785217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "frame rate range (" + frameRates 1786217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + ") is out of limits: " + FRAME_RATE_RANGE); 1787217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar frameRates = null; 1788b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1789b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1790216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang bitRates = Utils.parseIntRange(map.get("bitrate-range"), null); 1791216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang if (bitRates != null) { 1792216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang try { 1793216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang bitRates = bitRates.intersect(BITRATE_RANGE); 1794216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } catch (IllegalArgumentException e) { 1795216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang Log.w(TAG, "bitrate range (" + bitRates 1796216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang + ") is out of limits: " + BITRATE_RANGE); 1797216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang bitRates = null; 1798216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1799216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1800b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1801217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockSize.getWidth(), "block-size width must be power of two"); 1803217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockSize.getHeight(), "block-size height must be power of two"); 1805b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1806217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1807217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment.getWidth(), "alignment width must be power of two"); 1808217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo( 1809217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment.getHeight(), "alignment height must be power of two"); 1810217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1811217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // update block-size and alignment 1812217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits( 1813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer.MAX_VALUE, Integer.MAX_VALUE, Integer.MAX_VALUE, 1814217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(), 1815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar alignment.getWidth(), alignment.getHeight()); 1816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 18172fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if ((mParent.mError & ERROR_UNSUPPORTED) != 0 || mAllowMbOverride) { 1818217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // codec supports profiles that we don't know. 1819217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // Use supplied values clipped to platform limits 1820217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widths != null) { 1821217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = SIZE_RANGE.intersect(widths); 1822217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1823217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (heights != null) { 1824217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = SIZE_RANGE.intersect(heights); 1825217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (counts != null) { 1827217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = POSITIVE_INTEGERS.intersect( 1828217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(counts, mBlockWidth * mBlockHeight 1829217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRates != null) { 1832217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = POSITIVE_LONGS.intersect( 1833217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(blockRates, mBlockWidth * mBlockHeight 1834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1835217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRatios != null) { 1837217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = POSITIVE_RATIONALS.intersect( 1838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.scaleRange(blockRatios, 1839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight / blockSize.getHeight(), 1840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth / blockSize.getWidth())); 1841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1842217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ratios != null) { 1843217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = POSITIVE_RATIONALS.intersect(ratios); 1844217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1845217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (frameRates != null) { 1846217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates); 1847217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1848216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang if (bitRates != null) { 18492fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // only allow bitrate override if unsupported profiles were encountered 18502fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if ((mParent.mError & ERROR_UNSUPPORTED) != 0) { 18512fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar mBitrateRange = BITRATE_RANGE.intersect(bitRates); 18522fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } else { 18532fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar mBitrateRange = mBitrateRange.intersect(bitRates); 18542fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 1855216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1856217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else { 1857217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // no unsupported profile/levels, so restrict values to known limits 1858217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widths != null) { 1859217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = mWidthRange.intersect(widths); 1860217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1861217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (heights != null) { 1862217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = mHeightRange.intersect(heights); 1863b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1864217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (counts != null) { 1865217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = mBlockCountRange.intersect( 1866217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(counts, mBlockWidth * mBlockHeight 1867217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1868b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1869217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRates != null) { 1870217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = mBlocksPerSecondRange.intersect( 1871217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(blockRates, mBlockWidth * mBlockHeight 1872217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / blockSize.getWidth() / blockSize.getHeight())); 1873b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1874217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (blockRatios != null) { 1875217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = mBlockAspectRatioRange.intersect( 1876217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.scaleRange(blockRatios, 1877217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight / blockSize.getHeight(), 1878217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth / blockSize.getWidth())); 1879217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1880217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ratios != null) { 1881217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = mAspectRatioRange.intersect(ratios); 1882217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1883217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (frameRates != null) { 1884217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = mFrameRateRange.intersect(frameRates); 1885217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1886216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang if (bitRates != null) { 1887216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang mBitrateRange = mBitrateRange.intersect(bitRates); 1888216e11dcbb4d56699c1740c801489be0d57b16c4Chong Zhang } 1889217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1890217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar updateLimits(); 1891217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1892217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1893217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyBlockLimits( 1894217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int blockWidth, int blockHeight, 1895217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range<Integer> counts, Range<Long> rates, Range<Rational> ratios) { 1896217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(blockWidth, "blockWidth must be a power of two"); 1897217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(blockHeight, "blockHeight must be a power of two"); 1898217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1899217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int newBlockWidth = Math.max(blockWidth, mBlockWidth); 1900217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final int newBlockHeight = Math.max(blockHeight, mBlockHeight); 1901217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1902217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // factor will always be a power-of-2 1903217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int factor = 1904217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockWidth * newBlockHeight / mBlockWidth / mBlockHeight; 1905217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (factor != 1) { 1906217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = Utils.factorRange(mBlockCountRange, factor); 1907217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = Utils.factorRange( 1908217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange, factor); 1909217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = Utils.scaleRange( 1910217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange, 1911217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockHeight / mBlockHeight, 1912217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockWidth / mBlockWidth); 1913217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = Utils.factorRange( 1914217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange, newBlockWidth / mBlockWidth); 1915217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = Utils.factorRange( 1916217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange, newBlockHeight / mBlockHeight); 1917217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1918217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar factor = newBlockWidth * newBlockHeight / blockWidth / blockHeight; 1919217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (factor != 1) { 1920217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar counts = Utils.factorRange(counts, factor); 1921217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar rates = Utils.factorRange(rates, factor); 1922217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ratios = Utils.scaleRange( 1923217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ratios, newBlockHeight / blockHeight, 1924217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar newBlockWidth / blockWidth); 1925217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1926217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = mBlockCountRange.intersect(counts); 1927217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = mBlocksPerSecondRange.intersect(rates); 1928217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = mBlockAspectRatioRange.intersect(ratios); 1929217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockWidth = newBlockWidth; 1930217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockHeight = newBlockHeight; 1931217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1932217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1933217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyAlignment(int widthAlignment, int heightAlignment) { 1934217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(widthAlignment, "widthAlignment must be a power of two"); 1935217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar checkPowerOfTwo(heightAlignment, "heightAlignment must be a power of two"); 1936217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1937217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (widthAlignment > mBlockWidth || heightAlignment > mBlockHeight) { 1938217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // maintain assumption that 0 < alignment <= block-size 1939217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyBlockLimits( 1940217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.max(widthAlignment, mBlockWidth), 1941217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.max(heightAlignment, mBlockHeight), 1942217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar POSITIVE_INTEGERS, POSITIVE_LONGS, POSITIVE_RATIONALS); 1943b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 1944b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 1945217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthAlignment = Math.max(widthAlignment, mWidthAlignment); 1946217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightAlignment = Math.max(heightAlignment, mHeightAlignment); 1947217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1948217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = Utils.alignRange(mWidthRange, mWidthAlignment); 1949217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = Utils.alignRange(mHeightRange, mHeightAlignment); 1950217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 1951217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1952217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void updateLimits() { 1953217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // pixels -> blocks <- counts 1954217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = mHorizontalBlockRange.intersect( 1955217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(mWidthRange, mBlockWidth)); 1956217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = mHorizontalBlockRange.intersect( 1957217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1958217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getLower() / mVerticalBlockRange.getUpper(), 1959217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / mVerticalBlockRange.getLower())); 1960217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = mVerticalBlockRange.intersect( 1961217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Utils.factorRange(mHeightRange, mBlockHeight)); 1962217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = mVerticalBlockRange.intersect( 1963217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1964217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getLower() / mHorizontalBlockRange.getUpper(), 1965217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() / mHorizontalBlockRange.getLower())); 1966217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange = mBlockCountRange.intersect( 1967217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 1968217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getLower() 1969217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * mVerticalBlockRange.getLower(), 1970217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getUpper() 1971217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * mVerticalBlockRange.getUpper())); 1972217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockAspectRatioRange = mBlockAspectRatioRange.intersect( 1973217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational( 1974217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getLower(), mVerticalBlockRange.getUpper()), 1975217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational( 1976217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getUpper(), mVerticalBlockRange.getLower())); 1977217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1978217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // blocks -> pixels 1979217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mWidthRange = mWidthRange.intersect( 1980217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (mHorizontalBlockRange.getLower() - 1) * mBlockWidth + mWidthAlignment, 1981217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.getUpper() * mBlockWidth); 1982217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHeightRange = mHeightRange.intersect( 1983217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (mVerticalBlockRange.getLower() - 1) * mBlockHeight + mHeightAlignment, 1984217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange.getUpper() * mBlockHeight); 1985217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mAspectRatioRange = mAspectRatioRange.intersect( 1986217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(mWidthRange.getLower(), mHeightRange.getUpper()), 1987217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(mWidthRange.getUpper(), mHeightRange.getLower())); 1988217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1989217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit = Math.min( 1990217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mSmallerDimensionUpperLimit, 1991217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Math.min(mWidthRange.getUpper(), mHeightRange.getUpper())); 1992217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1993217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // blocks -> rate 1994217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlocksPerSecondRange = mBlocksPerSecondRange.intersect( 1995217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getLower() * (long)mFrameRateRange.getLower(), 1996217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBlockCountRange.getUpper() * (long)mFrameRateRange.getUpper()); 1997217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = mFrameRateRange.intersect( 1998217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mBlocksPerSecondRange.getLower() 1999217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / mBlockCountRange.getUpper()), 2000217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (int)(mBlocksPerSecondRange.getUpper() 2001217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar / (double)mBlockCountRange.getLower())); 2002217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2003217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2004217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyMacroBlockLimits( 2005217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxHorizontalBlocks, int maxVerticalBlocks, 2006217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBlocks, long maxBlocksPerSecond, 2007217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int blockWidth, int blockHeight, 2008217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int widthAlignment, int heightAlignment) { 20092fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar applyMacroBlockLimits( 20102fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 1 /* minHorizontalBlocks */, 1 /* minVerticalBlocks */, 20112fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxHorizontalBlocks, maxVerticalBlocks, 20122fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxBlocks, maxBlocksPerSecond, 20132fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar blockWidth, blockHeight, widthAlignment, heightAlignment); 20142fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 20152fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 20162fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar private void applyMacroBlockLimits( 20172fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int minHorizontalBlocks, int minVerticalBlocks, 20182fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int maxHorizontalBlocks, int maxVerticalBlocks, 20192fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int maxBlocks, long maxBlocksPerSecond, 20202fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int blockWidth, int blockHeight, 20212fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int widthAlignment, int heightAlignment) { 2022217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyAlignment(widthAlignment, heightAlignment); 2023217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyBlockLimits( 2024217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar blockWidth, blockHeight, Range.create(1, maxBlocks), 2025217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create(1L, maxBlocksPerSecond), 2026217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Range.create( 2027217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(1, maxVerticalBlocks), 2028217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Rational(maxHorizontalBlocks, 1))); 2029217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange = 2030217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mHorizontalBlockRange.intersect( 20312fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar Utils.divUp(minHorizontalBlocks, (mBlockWidth / blockWidth)), 20322fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxHorizontalBlocks / (mBlockWidth / blockWidth)); 2033217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange = 2034217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mVerticalBlockRange.intersect( 20352fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar Utils.divUp(minVerticalBlocks, (mBlockHeight / blockHeight)), 20362fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxVerticalBlocks / (mBlockHeight / blockHeight)); 2037217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2038217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2039217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLevelLimits() { 2040f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu long maxBlocksPerSecond = 0; 2041217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBlocks = 0; 2042217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxBps = 0; 2043217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxDPBBlocks = 0; 2044217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2045217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int errors = ERROR_NONE_SUPPORTED; 2046217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar CodecProfileLevel[] profileLevels = mParent.profileLevels; 2047217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String mime = mParent.getMimeType(); 2048217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 20495755817422700f6f5e8380921d1f5a728b677dd2Ronghua Wu if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_AVC)) { 2050217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 99; 2051217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = 1485; 2052217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 2053217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxDPBBlocks = 396; 2054217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 2055217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int MBPS = 0, FS = 0, BR = 0, DPB = 0; 2056217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean supported = true; 2057217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 2058217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel1: 2059217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 1485; FS = 99; BR = 64; DPB = 396; break; 2060217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel1b: 2061217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 1485; FS = 99; BR = 128; DPB = 396; break; 2062217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel11: 2063217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 3000; FS = 396; BR = 192; DPB = 900; break; 2064217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel12: 2065217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 6000; FS = 396; BR = 384; DPB = 2376; break; 2066217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel13: 2067217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 11880; FS = 396; BR = 768; DPB = 2376; break; 2068217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel2: 2069217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 11880; FS = 396; BR = 2000; DPB = 2376; break; 2070217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel21: 2071217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 19800; FS = 792; BR = 4000; DPB = 4752; break; 2072217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel22: 2073217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 20250; FS = 1620; BR = 4000; DPB = 8100; break; 2074217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel3: 2075217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 40500; FS = 1620; BR = 10000; DPB = 8100; break; 2076217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel31: 2077217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 108000; FS = 3600; BR = 14000; DPB = 18000; break; 2078217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel32: 2079217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 216000; FS = 5120; BR = 20000; DPB = 20480; break; 2080217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel4: 2081217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 245760; FS = 8192; BR = 20000; DPB = 32768; break; 2082217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel41: 2083217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 245760; FS = 8192; BR = 50000; DPB = 32768; break; 2084217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel42: 2085217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 522240; FS = 8704; BR = 50000; DPB = 34816; break; 2086217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel5: 2087217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 589824; FS = 22080; BR = 135000; DPB = 110400; break; 2088217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel51: 2089217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 983040; FS = 36864; BR = 240000; DPB = 184320; break; 2090217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCLevel52: 2091217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MBPS = 2073600; FS = 36864; BR = 240000; DPB = 184320; break; 2092217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2093217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized level " 2094217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 2095217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2096217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2097217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 2098217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh: 2099217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 1250; break; 2100217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh10: 2101217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 3000; break; 2102217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileExtended: 2103217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh422: 2104217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileHigh444: 2105217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unsupported profile " 2106217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2107217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNSUPPORTED; 2108217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar supported = false; 2109217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // fall through - treat as base profile 2110217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileBaseline: 2111217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.AVCProfileMain: 2112217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 1000; break; 2113217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2114217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 2115217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2116217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2117217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar BR *= 1000; 2118217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2119217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (supported) { 2120217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 2121217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2122217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 2123217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(FS, maxBlocks); 2124217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR, maxBps); 2125217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxDPBBlocks = Math.max(maxDPBBlocks, DPB); 2126981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } 2127217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2128217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8)); 2129217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits( 2130217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxLengthInBlocks, maxLengthInBlocks, 2131217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 2132217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16 /* blockWidth */, 16 /* blockHeight */, 2133217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 213434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG2)) { 213534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar int maxWidth = 11, maxHeight = 9, maxRate = 15; 213634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBlocks = 99; 213734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBlocksPerSecond = 1485; 213834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBps = 64000; 213934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar for (CodecProfileLevel profileLevel: profileLevels) { 214034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0; 214134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar boolean supported = true; 214234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar switch (profileLevel.profile) { 214334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2ProfileSimple: 214434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar switch (profileLevel.level) { 214534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2LevelML: 21462fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 15000; break; 214734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar default: 214834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar Log.w(TAG, "Unrecognized profile/level " 214934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar + profileLevel.profile + "/" 215034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar + profileLevel.level + " for " + mime); 215134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar errors |= ERROR_UNRECOGNIZED; 215234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar } 215334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar break; 215434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2ProfileMain: 215534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar switch (profileLevel.level) { 215634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2LevelLL: 21572a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 4000; break; 215834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2LevelML: 21592fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 15000; break; 216034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2LevelH14: 21612a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 60; W = 90; H = 68; MBPS = 183600; FS = 6120; BR = 60000; break; 216234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2LevelHL: 21632a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 60; W = 120; H = 68; MBPS = 244800; FS = 8160; BR = 80000; break; 21642a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar case CodecProfileLevel.MPEG2LevelHP: 21652a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 60; W = 120; H = 68; MBPS = 489600; FS = 8160; BR = 80000; break; 216634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar default: 216734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar Log.w(TAG, "Unrecognized profile/level " 216834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar + profileLevel.profile + "/" 216934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar + profileLevel.level + " for " + mime); 217034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar errors |= ERROR_UNRECOGNIZED; 217134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar } 217234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar break; 217334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2Profile422: 217434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2ProfileSNR: 217534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2ProfileSpatial: 217634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar case CodecProfileLevel.MPEG2ProfileHigh: 217734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar Log.i(TAG, "Unsupported profile " 217834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar + profileLevel.profile + " for " + mime); 217934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar errors |= ERROR_UNSUPPORTED; 218034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar supported = false; 218134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar break; 218234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar default: 218334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar Log.w(TAG, "Unrecognized profile " 218434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar + profileLevel.profile + " for " + mime); 218534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar errors |= ERROR_UNRECOGNIZED; 218634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar } 218734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar if (supported) { 218834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar errors &= ~ERROR_NONE_SUPPORTED; 218934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar } 219034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 219134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBlocks = Math.max(FS, maxBlocks); 219234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBps = Math.max(BR * 1000, maxBps); 219334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxWidth = Math.max(W, maxWidth); 219434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxHeight = Math.max(H, maxHeight); 219534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxRate = Math.max(FR, maxRate); 219634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar } 219734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar applyMacroBlockLimits(maxWidth, maxHeight, 219834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar maxBlocks, maxBlocksPerSecond, 219934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar 16 /* blockWidth */, 16 /* blockHeight */, 220034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar 1 /* widthAlignment */, 1 /* heightAlignment */); 220134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar mFrameRateRange = mFrameRateRange.intersect(12, maxRate); 2202217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) { 2203217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxWidth = 11, maxHeight = 9, maxRate = 15; 2204217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 99; 2205217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = 1485; 2206217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 2207217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 2208217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0; 22092fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar boolean strict = false; // true: W, H and FR are individual max limits 2210217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean supported = true; 2211217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 2212217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimple: 2213217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 2214217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level0: 22152fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = true; 2216217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break; 2217217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level1: 2218217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break; 2219217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level0b: 22202fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = true; 22212fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 128; break; 2222217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level2: 2223217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 5940; FS = 396; BR = 128; break; 2224217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level3: 2225217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 384; break; 2226217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level4a: 22272a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 30; W = 40; H = 30; MBPS = 36000; FS = 1200; BR = 4000; break; 2228217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level5: 22292a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 8000; break; 22302a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar case CodecProfileLevel.MPEG4Level6: 22312a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 30; W = 80; H = 45; MBPS = 108000; FS = 3600; BR = 12000; break; 2232217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2233217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile/level " 2234217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + "/" 2235217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 2236217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2237217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2238217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2239217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedSimple: 2240217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 2241217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level0: 2242217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level1: 2243217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 11; H = 9; MBPS = 2970; FS = 99; BR = 128; break; 2244217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level2: 2245217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 5940; FS = 396; BR = 384; break; 2246217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level3: 2247217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 768; break; 22482a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar case CodecProfileLevel.MPEG4Level3b: 22492a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 1500; break; 2250217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level4: 2251217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 44; H = 36; MBPS = 23760; FS = 792; BR = 3000; break; 2252217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4Level5: 2253217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 8000; break; 2254217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2255217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile/level " 2256217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + "/" 2257217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 2258217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2259217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2260217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2261217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileMain: // 2-4 2262217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileNbit: // 2 2263217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedRealTime: // 1-4 2264217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileCoreScalable: // 1-3 2265217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedCoding: // 1-4 2266217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileCore: // 1-2 2267217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedCore: // 1-4 2268217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimpleScalable: // 0-2 2269217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileHybrid: // 1-2 22702fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 22712fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // Studio profiles are not supported by our codecs. 22722fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 22732fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // Only profiles that can decode simple object types are considered. 22742fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // The following profiles are not able to. 2275217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileBasicAnimated: // 1-2 2276217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileScalableTexture: // 1 2277217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimpleFace: // 1-2 22782fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3 2279217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.MPEG4ProfileSimpleFBA: // 1-2 2280217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.i(TAG, "Unsupported profile " 2281217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2282217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNSUPPORTED; 2283217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar supported = false; 2284217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2285217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2286217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 2287217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2288217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2289217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2290217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (supported) { 2291217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 2292217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2293217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 2294217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(FS, maxBlocks); 2295217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR * 1000, maxBps); 22962fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (strict) { 22972fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxWidth = Math.max(W, maxWidth); 22982fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxHeight = Math.max(H, maxHeight); 22992fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxRate = Math.max(FR, maxRate); 23002fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } else { 23012fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // assuming max 60 fps frame rate and 1:2 aspect ratio 23022fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int maxDim = (int)Math.sqrt(FS * 2); 23032fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxWidth = Math.max(maxDim, maxWidth); 23042fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxHeight = Math.max(maxDim, maxHeight); 23052fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxRate = Math.max(Math.max(FR, 60), maxRate); 23062fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 2307981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } 2308217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits(maxWidth, maxHeight, 2309217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 2310217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16 /* blockWidth */, 16 /* blockHeight */, 2311217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 2312217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = mFrameRateRange.intersect(12, maxRate); 2313217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) { 2314217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxWidth = 11, maxHeight = 9, maxRate = 15; 23152fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int minWidth = maxWidth, minHeight = maxHeight; 23162fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int minAlignment = 16; 2317217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = 99; 2318217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = 1485; 2319217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 2320217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 23212fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0, minW = minWidth, minH = minHeight; 23222fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar boolean strict = false; // true: support only sQCIF, QCIF (maybe CIF) 2323217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 2324217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level10: 23252fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = true; // only supports sQCIF & QCIF 2326217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 15; W = 11; H = 9; BR = 1; MBPS = W * H * FR; break; 2327217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level20: 23282fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = true; // only supports sQCIF, QCIF & CIF 23292fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar FR = 30; W = 22; H = 18; BR = 2; MBPS = W * H * 15; break; 2330217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level30: 23312fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = true; // only supports sQCIF, QCIF & CIF 2332217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; BR = 6; MBPS = W * H * FR; break; 2333217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level40: 23342fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = true; // only supports sQCIF, QCIF & CIF 2335217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; W = 22; H = 18; BR = 32; MBPS = W * H * FR; break; 2336217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level45: 2337217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only implies level 10 support 23382fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar strict = profileLevel.profile == CodecProfileLevel.H263ProfileBaseline 23392fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar || profileLevel.profile == 23402fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar CodecProfileLevel.H263ProfileBackwardCompatible; 23412fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (!strict) { 23422fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minW = 1; minH = 1; minAlignment = 4; 23432fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 23442fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar FR = 15; W = 11; H = 9; BR = 2; MBPS = W * H * FR; break; 2345217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level50: 2346217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports 50fps for H > 15 23472fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minW = 1; minH = 1; minAlignment = 4; 2348217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; W = 22; H = 18; BR = 64; MBPS = W * H * 50; break; 2349217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level60: 2350217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports 50fps for H > 15 23512fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minW = 1; minH = 1; minAlignment = 4; 2352217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; W = 45; H = 18; BR = 128; MBPS = W * H * 50; break; 2353217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263Level70: 2354217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // only supports 50fps for H > 30 23552fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minW = 1; minH = 1; minAlignment = 4; 2356217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; W = 45; H = 36; BR = 256; MBPS = W * H * 50; break; 2357217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2358217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile 2359217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + "/" + profileLevel.level + " for " + mime); 2360217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2361217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2362217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 2363217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileBackwardCompatible: 2364217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileBaseline: 2365217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileH320Coding: 2366217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileHighCompression: 2367217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileHighLatency: 2368217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileInterlace: 2369217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileInternet: 2370217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileISWV2: 2371217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.H263ProfileISWV3: 2372217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2373217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2374217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 2375217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2376217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2377217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 23782fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (strict) { 23792fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // Strict levels define sub-QCIF min size and enumerated sizes. We cannot 23802fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // express support for "only sQCIF & QCIF (& CIF)" using VideoCapabilities 23812fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // but we can express "only QCIF (& CIF)", so set minimume size at QCIF. 23822fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // minW = 8; minH = 6; 23832fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minW = 11; minH = 9; 23842fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } else { 23852fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // any support for non-strict levels (including unrecognized profiles or 23862fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // levels) allow custom frame size support beyond supported limits 23872fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // (other than bitrate) 23882fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar mAllowMbOverride = true; 23892fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 2390217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 2391217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond); 2392217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(W * H, maxBlocks); 2393217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR * 64000, maxBps); 2394217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxWidth = Math.max(W, maxWidth); 2395217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxHeight = Math.max(H, maxHeight); 2396217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxRate = Math.max(FR, maxRate); 23972fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minWidth = Math.min(minW, minWidth); 23982fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minHeight = Math.min(minH, minHeight); 2399217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 24002fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // unless we encountered custom frame size support, limit size to QCIF and CIF 24012fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // using aspect ratio. 24022fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar if (!mAllowMbOverride) { 24032fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar mBlockAspectRatioRange = 24042fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar Range.create(new Rational(11, 9), new Rational(11, 9)); 24052fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar } 24062fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar applyMacroBlockLimits( 24072fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minWidth, minHeight, 24082fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxWidth, maxHeight, 2409217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 2410217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 16 /* blockWidth */, 16 /* blockHeight */, 24112fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar minAlignment /* widthAlignment */, minAlignment /* heightAlignment */); 2412217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mFrameRateRange = Range.create(1, maxRate); 2413f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) { 2414f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocks = Integer.MAX_VALUE; 2415f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocksPerSecond = Integer.MAX_VALUE; 2416217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2417f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu // TODO: set to 100Mbps for now, need a number for VP8 2418217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 100000000; 2419217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2420217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // profile levels are not indicative for VPx, but verify 2421217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // them nonetheless 2422217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 2423217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 2424217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version0: 2425217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version1: 2426217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version2: 2427217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8Level_Version3: 2428217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2429217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2430217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized level " 2431217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 2432217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2433217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2434217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 2435217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.VP8ProfileMain: 2436217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2437217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2438217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 2439217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2440217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2441217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2442217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 2443981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar } 2444981c344ee7a4472e2a331d66819c132267a681c6Lajos Molnar 2445f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu final int blockSize = 16; 2446217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits(Short.MAX_VALUE, Short.MAX_VALUE, 2447217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, blockSize, blockSize, 2448217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 2449f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP9)) { 2450f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocksPerSecond = 829440; 2451f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocks = 36864; 2452f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBps = 200000; 24538acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int maxDim = 512; 2454f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu 2455f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu for (CodecProfileLevel profileLevel: profileLevels) { 24568acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar long SR = 0; // luma sample rate 24578acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int FS = 0; // luma picture size 24588acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int BR = 0; // bit rate kbps 24598acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int D = 0; // luma dimension 2460f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu switch (profileLevel.level) { 2461f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level1: 24628acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 829440; FS = 36864; BR = 200; D = 512; break; 2463f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level11: 24648acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 2764800; FS = 73728; BR = 800; D = 768; break; 2465f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level2: 24668acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 4608000; FS = 122880; BR = 1800; D = 960; break; 2467f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level21: 24688acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 9216000; FS = 245760; BR = 3600; D = 1344; break; 2469f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level3: 24708acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 20736000; FS = 552960; BR = 7200; D = 2048; break; 2471f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level31: 24728acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 36864000; FS = 983040; BR = 12000; D = 2752; break; 2473f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level4: 24748acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 83558400; FS = 2228224; BR = 18000; D = 4160; break; 2475f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level41: 24768acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 160432128; FS = 2228224; BR = 30000; D = 4160; break; 2477f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level5: 24788acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 311951360; FS = 8912896; BR = 60000; D = 8384; break; 2479f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level51: 24808acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 588251136; FS = 8912896; BR = 120000; D = 8384; break; 2481f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level52: 24828acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 1176502272; FS = 8912896; BR = 180000; D = 8384; break; 2483f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level6: 24848acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 1176502272; FS = 35651584; BR = 180000; D = 16832; break; 2485f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level61: 24868acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 2353004544L; FS = 35651584; BR = 240000; D = 16832; break; 2487f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Level62: 24888acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar SR = 4706009088L; FS = 35651584; BR = 480000; D = 16832; break; 2489f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu default: 2490f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu Log.w(TAG, "Unrecognized level " 2491f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu + profileLevel.level + " for " + mime); 2492f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu errors |= ERROR_UNRECOGNIZED; 2493f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu } 2494f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu switch (profileLevel.profile) { 2495f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Profile0: 2496f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Profile1: 2497f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Profile2: 2498f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu case CodecProfileLevel.VP9Profile3: 24992fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar case CodecProfileLevel.VP9Profile2HDR: 25002fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar case CodecProfileLevel.VP9Profile3HDR: 2501f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu break; 2502f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu default: 2503f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu Log.w(TAG, "Unrecognized profile " 2504f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu + profileLevel.profile + " for " + mime); 2505f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu errors |= ERROR_UNRECOGNIZED; 2506f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu } 2507f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu errors &= ~ERROR_NONE_SUPPORTED; 2508f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocksPerSecond = Math.max(SR, maxBlocksPerSecond); 2509f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocks = Math.max(FS, maxBlocks); 2510f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBps = Math.max(BR * 1000, maxBps); 25118acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar maxDim = Math.max(D, maxDim); 2512f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu } 2513f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu 2514f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu final int blockSize = 8; 25158acc16473873053342f7a033ad08c4421dfb3cafLajos Molnar int maxLengthInBlocks = Utils.divUp(maxDim, blockSize); 2516f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocks = Utils.divUp(maxBlocks, blockSize * blockSize); 2517f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, blockSize * blockSize); 2518f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu 2519f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu applyMacroBlockLimits( 2520f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxLengthInBlocks, maxLengthInBlocks, 2521f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu maxBlocks, maxBlocksPerSecond, 2522f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu blockSize, blockSize, 2523f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu 1 /* widthAlignment */, 1 /* heightAlignment */); 25245755817422700f6f5e8380921d1f5a728b677dd2Ronghua Wu } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) { 25252fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar // CTBs are at least 8x8 so use 8x8 block size 25262fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar maxBlocks = 36864 >> 6; // 192x192 pixels == 576 8x8 blocks 2527217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = maxBlocks * 15; 2528217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 128000; 2529217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel profileLevel: profileLevels) { 2530217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar double FR = 0; 2531217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int FS = 0; 2532217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int BR = 0; 2533217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.level) { 25342fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar /* The HEVC spec talks only in a very convoluted manner about the 25352fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar existence of levels 1-3.1 for High tier, which could also be 25362fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar understood as 'decoders and encoders should treat these levels 25372fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar as if they were Main tier', so we do that. */ 2538217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel1: 2539217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel1: 2540217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 15; FS = 36864; BR = 128; break; 2541217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel2: 2542217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel2: 2543217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 122880; BR = 1500; break; 2544217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel21: 2545217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel21: 2546217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 245760; BR = 3000; break; 2547217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel3: 2548217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel3: 2549217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 552960; BR = 6000; break; 2550217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel31: 2551217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel31: 2552217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 33.75; FS = 983040; BR = 10000; break; 2553217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel4: 2554217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 2228224; BR = 12000; break; 2555217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel4: 2556217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 2228224; BR = 30000; break; 2557217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel41: 2558217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 2228224; BR = 20000; break; 2559217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel41: 2560217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 2228224; BR = 50000; break; 2561217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel5: 2562217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 8912896; BR = 25000; break; 2563217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel5: 2564217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 8912896; BR = 100000; break; 2565217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel51: 2566217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 8912896; BR = 40000; break; 2567217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel51: 2568217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 8912896; BR = 160000; break; 2569217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel52: 2570217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 8912896; BR = 60000; break; 2571217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel52: 2572217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 8912896; BR = 240000; break; 2573217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel6: 2574217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 35651584; BR = 60000; break; 2575217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel6: 2576217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 30; FS = 35651584; BR = 240000; break; 2577217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel61: 2578217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 35651584; BR = 120000; break; 2579217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel61: 2580217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 60; FS = 35651584; BR = 480000; break; 2581217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCMainTierLevel62: 2582217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 35651584; BR = 240000; break; 2583217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCHighTierLevel62: 2584217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar FR = 120; FS = 35651584; BR = 800000; break; 2585217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2586217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized level " 2587217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.level + " for " + mime); 2588217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2589217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2590217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar switch (profileLevel.profile) { 2591217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCProfileMain: 2592217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar case CodecProfileLevel.HEVCProfileMain10: 2593f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu case CodecProfileLevel.HEVCProfileMain10HDR10: 2594217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2595217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar default: 2596217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unrecognized profile " 2597217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar + profileLevel.profile + " for " + mime); 2598217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNRECOGNIZED; 2599217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2600217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2601217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* DPB logic: 2602217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (width * height <= FS / 4) DPB = 16; 2603217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar else if (width * height <= FS / 2) DPB = 12; 2604217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar else if (width * height <= FS * 0.75) DPB = 8; 2605217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar else DPB = 6; 2606217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 2607217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 26082fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar FS >>= 6; // convert pixels to blocks 2609217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors &= ~ERROR_NONE_SUPPORTED; 2610217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond); 2611217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks = Math.max(FS, maxBlocks); 2612217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = Math.max(BR * 1000, maxBps); 2613b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2614b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2615217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8)); 2616217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyMacroBlockLimits( 2617217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxLengthInBlocks, maxLengthInBlocks, 2618217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBlocks, maxBlocksPerSecond, 2619217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 8 /* blockWidth */, 8 /* blockHeight */, 2620217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 1 /* widthAlignment */, 1 /* heightAlignment */); 2621217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else { 2622217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Log.w(TAG, "Unsupported mime " + mime); 2623217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // using minimal bitrate here. should be overriden by 2624217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // info from media_codecs.xml 2625217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar maxBps = 64000; 2626217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar errors |= ERROR_UNSUPPORTED; 2627217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2628217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitrateRange = Range.create(1, maxBps); 2629217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent.mError |= errors; 2630217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2631217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2632217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2633217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 2634217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * A class that supports querying the encoding capabilities of a codec. 2635217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 2636217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final class EncoderCapabilities { 2637217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 2638217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the supported range of quality values. 2639217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * 2640217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * @hide 2641217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 2642217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getQualityRange() { 2643217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mQualityRange; 2644217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2645217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2646217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** 2647217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Returns the supported range of encoder complexity values. 2648217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * <p> 2649217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Some codecs may support multiple complexity levels, where higher 2650217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * complexity values use more encoder tools (e.g. perform more 2651217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * intensive calculations) to improve the quality or the compression 2652217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * ratio. Use a lower value to save power and/or time. 2653217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar */ 2654217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public Range<Integer> getComplexityRange() { 2655217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return mComplexityRange; 2656217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2657217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2658217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** Constant quality mode */ 2659217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final int BITRATE_MODE_CQ = 0; 2660217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** Variable bitrate mode */ 2661217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final int BITRATE_MODE_VBR = 1; 2662217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** Constant bitrate mode */ 2663217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static final int BITRATE_MODE_CBR = 2; 2664217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2665217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static final Feature[] bitrates = new Feature[] { 2666217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Feature("VBR", BITRATE_MODE_VBR, true), 2667217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Feature("CBR", BITRATE_MODE_CBR, false), 2668217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar new Feature("CQ", BITRATE_MODE_CQ, false) 2669b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar }; 2670b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2671217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private static int parseBitrateMode(String mode) { 2672217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Feature feat: bitrates) { 2673217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (feat.mName.equalsIgnoreCase(mode)) { 2674217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return feat.mValue; 2675217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2676217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2677217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return 0; 2678b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2679b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2680b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** 2681217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar * Query whether a bitrate mode is supported. 2682b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar */ 2683217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean isBitrateModeSupported(int mode) { 2684217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Feature feat: bitrates) { 2685217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mode == feat.mValue) { 2686217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return (mBitControl & (1 << mode)) != 0; 2687217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2688217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2689217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 2690b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 2691b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 2692217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mQualityRange; 2693217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Range<Integer> mComplexityRange; 2694217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private CodecCapabilities mParent; 2695217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2696217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /* no public constructor */ 2697217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private EncoderCapabilities() { } 2698217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2699b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 2700217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public static EncoderCapabilities create( 2701217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar MediaFormat info, CodecCapabilities parent) { 2702217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar EncoderCapabilities caps = new EncoderCapabilities(); 2703217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar caps.init(info, parent); 2704217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return caps; 2705217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2706217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2707217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 2708217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void init(MediaFormat info, CodecCapabilities parent) { 2709217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // no support for complexity or quality yet 2710217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mParent = parent; 2711217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mComplexityRange = Range.create(0, 0); 2712217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mQualityRange = Range.create(0, 0); 2713217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl = (1 << BITRATE_MODE_VBR); 2714217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2715217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar applyLevelLimits(); 2716217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar parseFromInfo(info); 2717217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2718217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2719217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void applyLevelLimits() { 2720217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar String mime = mParent.getMimeType(); 2721217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_FLAC)) { 2722217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mComplexityRange = Range.create(0, 8); 2723217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl = (1 << BITRATE_MODE_CQ); 2724217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_NB) 2725217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AMR_WB) 2726217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_ALAW) 2727217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_G711_MLAW) 2728217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar || mime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_MSGSM)) { 2729217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl = (1 << BITRATE_MODE_CBR); 2730217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2731217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2732217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2733217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private int mBitControl; 2734217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Integer mDefaultComplexity; 2735217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private Integer mDefaultQuality; 2736217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private String mQualityScale; 2737217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2738217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private void parseFromInfo(MediaFormat info) { 2739217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Map<String, Object> map = info.getMap(); 2740217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2741217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("complexity-range")) { 2742217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mComplexityRange = Utils 2743217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar .parseIntRange(info.getString("complexity-range"), mComplexityRange); 2744217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // TODO should we limit this to level limits? 2745217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2746217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("quality-range")) { 2747217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mQualityRange = Utils 2748217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar .parseIntRange(info.getString("quality-range"), mQualityRange); 2749217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2750217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (info.containsKey("feature-bitrate-control")) { 2751217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (String mode: info.getString("feature-bitrate-control").split(",")) { 2752217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mBitControl |= parseBitrateMode(mode); 2753217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2754217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2755217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2756217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 2757217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefaultComplexity = Integer.parseInt((String)map.get("complexity-default")); 2758217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (NumberFormatException e) { } 2759217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2760217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar try { 2761217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mDefaultQuality = Integer.parseInt((String)map.get("quality-default")); 2762217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } catch (NumberFormatException e) { } 2763217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2764217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar mQualityScale = (String)map.get("quality-scale"); 2765217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2766217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2767217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar private boolean supports( 2768217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer complexity, Integer quality, Integer profile) { 2769217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar boolean ok = true; 2770217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && complexity != null) { 2771217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mComplexityRange.contains(complexity); 2772217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2773217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && quality != null) { 2774217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = mQualityRange.contains(quality); 2775217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2776217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (ok && profile != null) { 2777217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (CodecProfileLevel pl: mParent.profileLevels) { 2778217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (pl.profile == profile) { 2779217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar profile = null; 2780217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2781217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2782217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2783217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar ok = profile == null; 2784217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2785217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return ok; 2786217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2787217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2788217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 2789217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public void setDefaultFormat(MediaFormat format) { 2790217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // don't list trivial quality/complexity as default for now 2791217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mQualityRange.getUpper().equals(mQualityRange.getLower()) 2792217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mDefaultQuality != null) { 2793217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_QUALITY, mDefaultQuality); 2794217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2795217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (!mComplexityRange.getUpper().equals(mComplexityRange.getLower()) 2796217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar && mDefaultComplexity != null) { 2797217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_COMPLEXITY, mDefaultComplexity); 2798217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2799217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // bitrates are listed in order of preference 2800217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar for (Feature feat: bitrates) { 2801217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if ((mBitControl & (1 << feat.mValue)) != 0) { 2802217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar format.setInteger(MediaFormat.KEY_BITRATE_MODE, feat.mValue); 2803217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar break; 2804217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2805217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2806217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2807217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2808217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar /** @hide */ 2809217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar public boolean supportsFormat(MediaFormat format) { 2810217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final Map<String, Object> map = format.getMap(); 2811217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar final String mime = mParent.getMimeType(); 2812217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2813217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer mode = (Integer)map.get(MediaFormat.KEY_BITRATE_MODE); 2814217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (mode != null && !isBitrateModeSupported(mode)) { 2815217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return false; 2816217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2817217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2818217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer complexity = (Integer)map.get(MediaFormat.KEY_COMPLEXITY); 2819217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (MediaFormat.MIMETYPE_AUDIO_FLAC.equalsIgnoreCase(mime)) { 2820217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer flacComplexity = 2821217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar (Integer)map.get(MediaFormat.KEY_FLAC_COMPRESSION_LEVEL); 2822217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (complexity == null) { 2823217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar complexity = flacComplexity; 28245c5978985a3457539d1f3b611f23d26b77484536Andreas Gampe } else if (flacComplexity != null && !complexity.equals(flacComplexity)) { 2825217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException( 2826217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar "conflicting values for complexity and " + 2827217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar "flac-compression-level"); 2828217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2829217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2830217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2831217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar // other audio parameters 2832217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE); 2833217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (MediaFormat.MIMETYPE_AUDIO_AAC.equalsIgnoreCase(mime)) { 2834217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer aacProfile = (Integer)map.get(MediaFormat.KEY_AAC_PROFILE); 2835217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar if (profile == null) { 2836217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar profile = aacProfile; 28375c5978985a3457539d1f3b611f23d26b77484536Andreas Gampe } else if (aacProfile != null && !aacProfile.equals(profile)) { 2838217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar throw new IllegalArgumentException( 2839217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar "conflicting values for profile and aac-profile"); 2840217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2841217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar } 2842217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2843217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar Integer quality = (Integer)map.get(MediaFormat.KEY_QUALITY); 2844217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar 2845217474682ab9c551f331a598cf99d4e8d50f2a8dLajos Molnar return supports(complexity, quality, profile); 2846b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 284760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber }; 284860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 2849c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main /** 2850c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * Encapsulates the profiles available for a codec component. 2851c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * <p>You can get a set of {@link MediaCodecInfo.CodecProfileLevel} objects for a given 2852c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * {@link MediaCodecInfo} object from the 2853c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * {@link MediaCodecInfo.CodecCapabilities#profileLevels} field. 2854c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main */ 285560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final class CodecProfileLevel { 285660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_AVCPROFILETYPE 285760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileBaseline = 0x01; 285860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileMain = 0x02; 285960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileExtended = 0x04; 286060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh = 0x08; 286160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh10 = 0x10; 286260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh422 = 0x20; 286360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCProfileHigh444 = 0x40; 286460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 286560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_AVCLEVELTYPE 286660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel1 = 0x01; 286760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel1b = 0x02; 286860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel11 = 0x04; 286960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel12 = 0x08; 287060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel13 = 0x10; 287160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel2 = 0x20; 287260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel21 = 0x40; 287360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel22 = 0x80; 287460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel3 = 0x100; 287560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel31 = 0x200; 287660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel32 = 0x400; 287760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel4 = 0x800; 287860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel41 = 0x1000; 287960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel42 = 0x2000; 288060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel5 = 0x4000; 288160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AVCLevel51 = 0x8000; 2882b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public static final int AVCLevel52 = 0x10000; 288360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 288460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_H263PROFILETYPE 288560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileBaseline = 0x01; 288660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileH320Coding = 0x02; 288760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileBackwardCompatible = 0x04; 288860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileISWV2 = 0x08; 288960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileISWV3 = 0x10; 289060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileHighCompression = 0x20; 289160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileInternet = 0x40; 289260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileInterlace = 0x80; 289360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263ProfileHighLatency = 0x100; 289460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 289560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_H263LEVELTYPE 289660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level10 = 0x01; 289760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level20 = 0x02; 289860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level30 = 0x04; 289960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level40 = 0x08; 290060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level45 = 0x10; 290160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level50 = 0x20; 290260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level60 = 0x40; 290360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int H263Level70 = 0x80; 290460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 290560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_MPEG4PROFILETYPE 290660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimple = 0x01; 290760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimpleScalable = 0x02; 290860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileCore = 0x04; 290960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileMain = 0x08; 291060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileNbit = 0x10; 291160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileScalableTexture = 0x20; 291260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimpleFace = 0x40; 291360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileSimpleFBA = 0x80; 291460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileBasicAnimated = 0x100; 291560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileHybrid = 0x200; 291660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedRealTime = 0x400; 291760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileCoreScalable = 0x800; 291860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedCoding = 0x1000; 291960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedCore = 0x2000; 292060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedScalable = 0x4000; 292160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4ProfileAdvancedSimple = 0x8000; 292260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 292360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_VIDEO_MPEG4LEVELTYPE 292460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level0 = 0x01; 292560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level0b = 0x02; 292660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level1 = 0x04; 292760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level2 = 0x08; 292860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level3 = 0x10; 29292a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar public static final int MPEG4Level3b = 0x18; 293060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level4 = 0x20; 293160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level4a = 0x40; 293260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int MPEG4Level5 = 0x80; 29332a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar public static final int MPEG4Level6 = 0x100; 293460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 293534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar // from OMX_VIDEO_MPEG2PROFILETYPE 293634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2ProfileSimple = 0x00; 293734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2ProfileMain = 0x01; 293834265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2Profile422 = 0x02; 293934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2ProfileSNR = 0x03; 294034265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2ProfileSpatial = 0x04; 294134265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2ProfileHigh = 0x05; 294234265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar 294334265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar // from OMX_VIDEO_MPEG2LEVELTYPE 294434265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2LevelLL = 0x00; 294534265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2LevelML = 0x01; 294634265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2LevelH14 = 0x02; 294734265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar public static final int MPEG2LevelHL = 0x03; 29482a4001ee62f3374d7fffed72d71f77c5a833c331Lajos Molnar public static final int MPEG2LevelHP = 0x04; 294934265cd94f76cc18648c310e4f120d280bf3a0a4Harish Mahendrakar 295060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber // from OMX_AUDIO_AACPROFILETYPE 295160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectMain = 1; 295260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectLC = 2; 295360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectSSR = 3; 295460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectLTP = 4; 295560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectHE = 5; 295660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectScalable = 6; 295760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectERLC = 17; 29587c1cb0d5a5420823e63d59daf140844921407e29Jean-Michel Trivi public static final int AACObjectERScalable = 20; 295960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectLD = 23; 296060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectHE_PS = 29; 296160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public static final int AACObjectELD = 39; 296260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 2963e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin // from OMX_VIDEO_VP8LEVELTYPE 2964e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version0 = 0x01; 2965e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version1 = 0x02; 2966e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version2 = 0x04; 2967e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8Level_Version3 = 0x08; 2968e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin 2969e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin // from OMX_VIDEO_VP8PROFILETYPE 2970e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin public static final int VP8ProfileMain = 0x01; 2971e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin 2972f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu // from OMX_VIDEO_VP9PROFILETYPE 2973f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang public static final int VP9Profile0 = 0x01; 2974f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang public static final int VP9Profile1 = 0x02; 2975f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang public static final int VP9Profile2 = 0x04; 2976f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang public static final int VP9Profile3 = 0x08; 2977f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang // HDR profiles also support passing HDR metadata 2978f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang public static final int VP9Profile2HDR = 0x1000; 2979f0ef572fd0dfb8304db391e5643cd53b7625fd0aHangyu Kuang public static final int VP9Profile3HDR = 0x2000; 2980f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu 2981f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu // from OMX_VIDEO_VP9LEVELTYPE 29829186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level1 = 0x1; 29839186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level11 = 0x2; 29849186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level2 = 0x4; 29859186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level21 = 0x8; 29869186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level3 = 0x10; 29879186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level31 = 0x20; 29889186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level4 = 0x40; 29899186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level41 = 0x80; 29909186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level5 = 0x100; 29919186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level51 = 0x200; 29929186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level52 = 0x400; 29939186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level6 = 0x800; 29949186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level61 = 0x1000; 29959186c38fceedd4e517d764216b4f71561f3baf97Hangyu Kuang public static final int VP9Level62 = 0x2000; 2996f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu 2997aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad // from OMX_VIDEO_HEVCPROFILETYPE 2998f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu public static final int HEVCProfileMain = 0x01; 2999f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu public static final int HEVCProfileMain10 = 0x02; 3000f2615b8b339b812ad6b309d5ec116eb0add320f3Ronghua Wu public static final int HEVCProfileMain10HDR10 = 0x1000; 3001aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad 3002aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad // from OMX_VIDEO_HEVCLEVELTYPE 3003aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel1 = 0x1; 3004aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel1 = 0x2; 3005aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel2 = 0x4; 3006aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel2 = 0x8; 3007aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel21 = 0x10; 3008aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel21 = 0x20; 3009aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel3 = 0x40; 3010aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel3 = 0x80; 3011aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel31 = 0x100; 3012aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel31 = 0x200; 3013aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel4 = 0x400; 3014aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel4 = 0x800; 3015aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel41 = 0x1000; 3016aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel41 = 0x2000; 3017aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel5 = 0x4000; 3018aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel5 = 0x8000; 3019aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel51 = 0x10000; 3020aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel51 = 0x20000; 3021aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel52 = 0x40000; 3022aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel52 = 0x80000; 3023aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel6 = 0x100000; 3024aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel6 = 0x200000; 3025aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel61 = 0x400000; 3026aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel61 = 0x800000; 3027aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCMainTierLevel62 = 0x1000000; 3028aca5de7ca13b0a92e64379913aee6c20e7e2e08eRachad public static final int HEVCHighTierLevel62 = 0x2000000; 3029e72409fe779f620382c5bd0b82f4a32ac91d9fe4Kunter Gultekin 30302fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar private static final int HEVCHighTierLevels = 30312fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 | 30322fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 | 30332fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 | 30342fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar HEVCHighTierLevel62; 30352fc9c6925a51b18452e8080d5ac2d50babd0c866Lajos Molnar 3036d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu // from OMX_VIDEO_DOLBYVISIONPROFILETYPE 303732e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvavPer = 0x1; 303832e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvavPen = 0x2; 303932e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvheDer = 0x4; 304032e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvheDen = 0x8; 304132e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvheDtr = 0x10; 304232e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvheStn = 0x20; 304332e537c610b66ca975e6d9e4cf5dadb4a7cb62d3Ronghua Wu public static final int DolbyVisionProfileDvheDth = 0x40; 3044f939e4adf1b3c6f9d7d26def48503654801f700dHangyu Kuang public static final int DolbyVisionProfileDvheDtb = 0x80; 3045d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu 3046d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu // from OMX_VIDEO_DOLBYVISIONLEVELTYPE 3047d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelHd24 = 0x1; 3048d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelHd30 = 0x2; 3049d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelFhd24 = 0x4; 3050d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelFhd30 = 0x8; 3051d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelFhd60 = 0x10; 3052d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelUhd24 = 0x20; 3053d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelUhd30 = 0x40; 3054d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelUhd48 = 0x80; 3055d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu public static final int DolbyVisionLevelUhd60 = 0x100; 3056d6c2a76dcf8160e56846be1e82893f0c89527582Ronghua Wu 305760d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 305860d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Defined in the OpenMAX IL specs, depending on the type of media 305960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * this can be OMX_VIDEO_AVCPROFILETYPE, OMX_VIDEO_H263PROFILETYPE, 3060f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu * OMX_VIDEO_MPEG4PROFILETYPE, OMX_VIDEO_VP8PROFILETYPE or OMX_VIDEO_VP9PROFILETYPE. 306160d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 306260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public int profile; 306360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 306460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber /** 306560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * Defined in the OpenMAX IL specs, depending on the type of media 306660d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber * this can be OMX_VIDEO_AVCLEVELTYPE, OMX_VIDEO_H263LEVELTYPE 3067f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu * OMX_VIDEO_MPEG4LEVELTYPE, OMX_VIDEO_VP8LEVELTYPE or OMX_VIDEO_VP9LEVELTYPE. 3068f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu * 3069f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu * Note that VP9 decoder on platforms before {@link android.os.Build.VERSION_CODES#N} may 3070f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu * not advertise a profile level support. For those VP9 decoders, please use 3071f37f9ba8c8ee8629399981d710dcb9f93a5fb31dRonghua Wu * {@link VideoCapabilities} to determine the codec capabilities. 307260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber */ 307360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public int level; 307460d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber }; 307560d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber 3076ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber /** 3077ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber * Enumerates the capabilities of the codec component. Since a single 3078ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber * component can support data of a variety of types, the type has to be 3079ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber * specified to yield a meaningful result. 3080c06bb7f5b9c6be9d121e3f5b4ee7cd31c99f6879Scott Main * @param type The MIME type to query 3081ba9269a5855b6d9d581af09077caafbd45180b41Andreas Huber */ 308260d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber public final CodecCapabilities getCapabilitiesForType( 308360d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber String type) { 3084b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar CodecCapabilities caps = mCaps.get(type); 3085b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (caps == null) { 3086b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar throw new IllegalArgumentException("codec does not support type"); 3087b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 3088b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar // clone writable object 3089b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return caps.dup(); 3090b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 3091b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 3092b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar /** @hide */ 3093b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar public MediaCodecInfo makeRegular() { 3094b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar ArrayList<CodecCapabilities> caps = new ArrayList<CodecCapabilities>(); 3095b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar for (CodecCapabilities c: mCaps.values()) { 3096b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (c.isRegular()) { 3097b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar caps.add(c); 3098b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 3099b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 3100b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar if (caps.size() == 0) { 3101b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return null; 3102b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } else if (caps.size() == mCaps.size()) { 3103b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return this; 3104b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar } 3105b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar 3106b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar return new MediaCodecInfo( 3107b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar mName, mIsEncoder, 3108b58dc3132272a5ec1ad4792c3c9d48b4198bd57fLajos Molnar caps.toArray(new CodecCapabilities[caps.size()])); 310960d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber } 311060d610bf103379277a4b29a7ead4f013f6128e4eAndreas Huber} 3111