diff --git a/api/current.txt b/api/current.txt index 87cd2d6788191..dc83f6eff101e 100644 --- a/api/current.txt +++ b/api/current.txt @@ -15186,6 +15186,7 @@ package android.media { method public android.media.MediaCodecInfo.AudioCapabilities getAudioCapabilities(); method public android.media.MediaFormat getDefaultFormat(); method public android.media.MediaCodecInfo.EncoderCapabilities getEncoderCapabilities(); + method public int getMaxSupportedInstances(); method public java.lang.String getMimeType(); method public android.media.MediaCodecInfo.VideoCapabilities getVideoCapabilities(); method public final boolean isFeatureRequired(java.lang.String); diff --git a/api/system-current.txt b/api/system-current.txt index 9e635bf54fd38..ac80474f37d0f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -16398,6 +16398,7 @@ package android.media { method public android.media.MediaCodecInfo.AudioCapabilities getAudioCapabilities(); method public android.media.MediaFormat getDefaultFormat(); method public android.media.MediaCodecInfo.EncoderCapabilities getEncoderCapabilities(); + method public int getMaxSupportedInstances(); method public java.lang.String getMimeType(); method public android.media.MediaCodecInfo.VideoCapabilities getVideoCapabilities(); method public final boolean isFeatureRequired(java.lang.String); diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java index ebf73da0b82fa..ce06e6589fac4 100644 --- a/media/java/android/media/MediaCodecInfo.java +++ b/media/java/android/media/MediaCodecInfo.java @@ -124,6 +124,8 @@ public final class MediaCodecInfo { private static final Range SIZE_RANGE = Range.create(1, 32768); private static final Range FRAME_RATE_RANGE = Range.create(0, 960); private static final Range BITRATE_RANGE = Range.create(0, 500000000); + private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32; + private static final int MAX_SUPPORTED_INSTANCES_LIMIT = 256; // found stuff that is not supported by framework (=> this should not happen) private static final int ERROR_UNRECOGNIZED = (1 << 0); @@ -147,6 +149,7 @@ public final class MediaCodecInfo { // CLASSIFICATION private String mMime; + private int mMaxSupportedInstances; // LEGACY FIELDS @@ -366,6 +369,18 @@ public final class MediaCodecInfo { return mMime; } + /** + * Returns the max number of the supported concurrent codec instances. + *

+ * This is a hint for an upper bound. Applications should not expect to successfully + * operate more instances than the returned value, but the actual number of + * concurrently operable instances may be less as it depends on the available + * resources at time of use. + */ + public int getMaxSupportedInstances() { + return mMaxSupportedInstances; + } + private boolean isAudio() { return mAudioCaps != null; } @@ -467,6 +482,15 @@ public final class MediaCodecInfo { mEncoderCaps.setDefaultFormat(mDefaultFormat); } + final Map global = MediaCodecList.getGlobalSettings(); + mMaxSupportedInstances = Utils.parseIntSafely( + global.get("max-supported-instances"), DEFAULT_MAX_SUPPORTED_INSTANCES); + + int maxInstances = Utils.parseIntSafely( + map.get("max-supported-instances"), mMaxSupportedInstances); + mMaxSupportedInstances = + Range.create(1, MAX_SUPPORTED_INSTANCES_LIMIT).clamp(maxInstances); + for (Feature feat: getValidFeatures()) { String key = MediaFormat.KEY_FEATURE_ + feat.mName; Integer yesNo = (Integer)map.get(key); diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java index 7fd01867b5928..f44e048397d45 100644 --- a/media/java/android/media/MediaCodecList.java +++ b/media/java/android/media/MediaCodecList.java @@ -21,6 +21,7 @@ import android.util.Log; import android.media.MediaCodecInfo; import java.util.ArrayList; import java.util.Arrays; +import java.util.Map; /** * Allows you to enumerate available codecs, each specified as a {@link MediaCodecInfo} object, @@ -61,13 +62,19 @@ final public class MediaCodecList { return sRegularCodecInfos[index]; } + /* package private */ static final Map getGlobalSettings() { + return sGlobalSettings; + } + private static Object sInitLock = new Object(); private static MediaCodecInfo[] sAllCodecInfos; private static MediaCodecInfo[] sRegularCodecInfos; + private static Map sGlobalSettings; private static final void initCodecList() { synchronized (sInitLock) { if (sRegularCodecInfos == null) { + sGlobalSettings = native_getGlobalSettings(); int count = native_getCodecCount(); ArrayList regulars = new ArrayList(); ArrayList all = new ArrayList(); @@ -112,6 +119,8 @@ final public class MediaCodecList { /* package private */ static native final MediaCodecInfo.CodecCapabilities getCodecCapabilities(int index, String type); + /* package private */ static native final Map native_getGlobalSettings(); + /* package private */ static native final int findCodecByName(String codec); /** @hide */ diff --git a/media/jni/android_media_MediaCodecList.cpp b/media/jni/android_media_MediaCodecList.cpp index f8c349b54c532..82dd48dffeae8 100644 --- a/media/jni/android_media_MediaCodecList.cpp +++ b/media/jni/android_media_MediaCodecList.cpp @@ -262,6 +262,27 @@ static jobject android_media_MediaCodecList_getCodecCapabilities( return caps; } +static jobject android_media_MediaCodecList_getGlobalSettings(JNIEnv *env, jobject /* thiz */) { + sp mcl = getCodecList(env); + if (mcl == NULL) { + // Runtime exception already pending. + return NULL; + } + + const sp settings = mcl->getGlobalSettings(); + if (settings == NULL) { + jniThrowException(env, "java/lang/RuntimeException", "cannot get global settings"); + return NULL; + } + + jobject settingsObj = NULL; + if (ConvertMessageToMap(env, settings, &settingsObj)) { + return NULL; + } + + return settingsObj; +} + static void android_media_MediaCodecList_native_init(JNIEnv* /* env */) { } @@ -277,6 +298,10 @@ static JNINativeMethod gMethods[] = { "(ILjava/lang/String;)Landroid/media/MediaCodecInfo$CodecCapabilities;", (void *)android_media_MediaCodecList_getCodecCapabilities }, + { "native_getGlobalSettings", + "()Ljava/util/Map;", + (void *)android_media_MediaCodecList_getGlobalSettings }, + { "findCodecByName", "(Ljava/lang/String;)I", (void *)android_media_MediaCodecList_findCodecByName },