Loading media/java/android/media/MediaCodecInfo.java +38 −7 Original line number Diff line number Diff line Loading @@ -934,15 +934,27 @@ public final class MediaCodecInfo { } } levelCaps = createFromProfileLevel(mMime, profile, maxLevel); // remove profile from this format otherwise levelCaps.isFormatSupported will // get into this same conditon and loop forever. Map<String, Object> mapWithoutProfile = new HashMap<>(map); mapWithoutProfile.remove(MediaFormat.KEY_PROFILE); MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile); if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) { // We must remove the profile from this format otherwise levelCaps.isFormatSupported // will get into this same condition and loop forever. Furthermore, since levelCaps // does not contain features and bitrate specific keys, keep only keys relevant for // a level check. Map<String, Object> levelCriticalFormatMap = new HashMap<>(map); final Set<String> criticalKeys = isVideo() ? VideoCapabilities.VIDEO_LEVEL_CRITICAL_FORMAT_KEYS : isAudio() ? AudioCapabilities.AUDIO_LEVEL_CRITICAL_FORMAT_KEYS : null; // critical keys will always contain KEY_MIME, but should also contain others to be // meaningful if (criticalKeys != null && criticalKeys.size() > 1 && levelCaps != null) { levelCriticalFormatMap.keySet().retainAll(criticalKeys); MediaFormat levelCriticalFormat = new MediaFormat(levelCriticalFormatMap); if (!levelCaps.isFormatSupported(levelCriticalFormat)) { return false; } } } if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) { return false; } Loading Loading @@ -1633,6 +1645,16 @@ public final class MediaCodecInfo { } } /* package private */ // must not contain KEY_PROFILE static final Set<String> AUDIO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of( // We don't set level-specific limits for audio codecs today. Key candidates would // be sample rate, bit rate or channel count. // MediaFormat.KEY_SAMPLE_RATE, // MediaFormat.KEY_CHANNEL_COUNT, // MediaFormat.KEY_BIT_RATE, MediaFormat.KEY_MIME); /** @hide */ public boolean supportsFormat(MediaFormat format) { Map<String, Object> map = format.getMap(); Loading Loading @@ -2357,6 +2379,15 @@ public final class MediaCodecInfo { return ok; } /* package private */ // must not contain KEY_PROFILE static final Set<String> VIDEO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of( MediaFormat.KEY_WIDTH, MediaFormat.KEY_HEIGHT, MediaFormat.KEY_FRAME_RATE, MediaFormat.KEY_BIT_RATE, MediaFormat.KEY_MIME); /** * @hide * @throws java.lang.ClassCastException */ Loading Loading
media/java/android/media/MediaCodecInfo.java +38 −7 Original line number Diff line number Diff line Loading @@ -934,15 +934,27 @@ public final class MediaCodecInfo { } } levelCaps = createFromProfileLevel(mMime, profile, maxLevel); // remove profile from this format otherwise levelCaps.isFormatSupported will // get into this same conditon and loop forever. Map<String, Object> mapWithoutProfile = new HashMap<>(map); mapWithoutProfile.remove(MediaFormat.KEY_PROFILE); MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile); if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) { // We must remove the profile from this format otherwise levelCaps.isFormatSupported // will get into this same condition and loop forever. Furthermore, since levelCaps // does not contain features and bitrate specific keys, keep only keys relevant for // a level check. Map<String, Object> levelCriticalFormatMap = new HashMap<>(map); final Set<String> criticalKeys = isVideo() ? VideoCapabilities.VIDEO_LEVEL_CRITICAL_FORMAT_KEYS : isAudio() ? AudioCapabilities.AUDIO_LEVEL_CRITICAL_FORMAT_KEYS : null; // critical keys will always contain KEY_MIME, but should also contain others to be // meaningful if (criticalKeys != null && criticalKeys.size() > 1 && levelCaps != null) { levelCriticalFormatMap.keySet().retainAll(criticalKeys); MediaFormat levelCriticalFormat = new MediaFormat(levelCriticalFormatMap); if (!levelCaps.isFormatSupported(levelCriticalFormat)) { return false; } } } if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) { return false; } Loading Loading @@ -1633,6 +1645,16 @@ public final class MediaCodecInfo { } } /* package private */ // must not contain KEY_PROFILE static final Set<String> AUDIO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of( // We don't set level-specific limits for audio codecs today. Key candidates would // be sample rate, bit rate or channel count. // MediaFormat.KEY_SAMPLE_RATE, // MediaFormat.KEY_CHANNEL_COUNT, // MediaFormat.KEY_BIT_RATE, MediaFormat.KEY_MIME); /** @hide */ public boolean supportsFormat(MediaFormat format) { Map<String, Object> map = format.getMap(); Loading Loading @@ -2357,6 +2379,15 @@ public final class MediaCodecInfo { return ok; } /* package private */ // must not contain KEY_PROFILE static final Set<String> VIDEO_LEVEL_CRITICAL_FORMAT_KEYS = Set.of( MediaFormat.KEY_WIDTH, MediaFormat.KEY_HEIGHT, MediaFormat.KEY_FRAME_RATE, MediaFormat.KEY_BIT_RATE, MediaFormat.KEY_MIME); /** * @hide * @throws java.lang.ClassCastException */ Loading