Merge "media: check profile, level and bitrate for isFormatSupported" into nyc-dev

This commit is contained in:
Lajos Molnar
2016-05-26 06:14:03 +00:00
committed by Android (Google) Code Review
2 changed files with 103 additions and 5 deletions

View File

@@ -567,6 +567,34 @@ public final class MediaCodecInfo {
return false;
}
}
Integer profile = (Integer)map.get(MediaFormat.KEY_PROFILE);
Integer level = (Integer)map.get(MediaFormat.KEY_LEVEL);
if (profile != null) {
if (!supportsProfileLevel(profile, level)) {
return false;
}
// If we recognize this profile, check that this format is supported by the
// highest level supported by the codec for that profile. (Ignore specified
// level beyond the above profile/level check as level is only used as a
// guidance. E.g. AVC Level 1 CIF format is supported if codec supports level 1.1
// even though max size for Level 1 is QCIF. However, MPEG2 Simple Profile
// 1080p format is not supported even if codec supports Main Profile Level High,
// as Simple Profile does not support 1080p.
CodecCapabilities levelCaps = null;
int maxLevel = 0;
for (CodecProfileLevel pl : profileLevels) {
if (pl.profile == profile && pl.level > maxLevel) {
maxLevel = pl.level;
}
}
levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
if (levelCaps != null && !levelCaps.isFormatSupported(format)) {
return false;
}
}
if (mAudioCaps != null && !mAudioCaps.supportsFormat(format)) {
return false;
}
@@ -579,6 +607,57 @@ public final class MediaCodecInfo {
return true;
}
private static boolean supportsBitrate(
Range<Integer> bitrateRange, MediaFormat format) {
Map<String, Object> map = format.getMap();
// consider max bitrate over average bitrate for support
Integer maxBitrate = (Integer)map.get(MediaFormat.KEY_MAX_BIT_RATE);
Integer bitrate = (Integer)map.get(MediaFormat.KEY_BIT_RATE);
if (bitrate == null) {
bitrate = maxBitrate;
} else if (maxBitrate != null) {
bitrate = Math.max(bitrate, maxBitrate);
}
if (bitrate != null && bitrate > 0) {
return bitrateRange.contains(bitrate);
}
return true;
}
private boolean supportsProfileLevel(int profile, Integer level) {
for (CodecProfileLevel pl: profileLevels) {
if (pl.profile != profile) {
continue;
}
// AAC does not use levels
if (level == null || mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_AUDIO_AAC)) {
return true;
}
// H.263 levels are not completely ordered:
// Level45 support only implies Level10 support
if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
if (pl.level != level && pl.level == CodecProfileLevel.H263Level45
&& level > CodecProfileLevel.H263Level10) {
continue;
}
}
if (pl.level >= level) {
// if we recognize the listed profile/level, we must also recognize the
// profile/level arguments.
if (createFromProfileLevel(mMime, profile, pl.level) != null) {
return createFromProfileLevel(mMime, profile, level) != null;
}
return true;
}
}
return false;
}
// errors while reading profile levels - accessed from sister capabilities
int mError;
@@ -1004,10 +1083,15 @@ public final class MediaCodecInfo {
Map<String, Object> map = format.getMap();
Integer sampleRate = (Integer)map.get(MediaFormat.KEY_SAMPLE_RATE);
Integer channels = (Integer)map.get(MediaFormat.KEY_CHANNEL_COUNT);
if (!supports(sampleRate, channels)) {
return false;
}
if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
return false;
}
// nothing to do for:
// KEY_CHANNEL_MASK: codecs don't get this
// KEY_IS_ADTS: required feature for all AAC decoders
@@ -1310,8 +1394,7 @@ public final class MediaCodecInfo {
return supports(width, height, null);
}
private boolean supports(
Integer width, Integer height, Number rate) {
private boolean supports(Integer width, Integer height, Number rate) {
boolean ok = true;
if (ok && width != null) {
@@ -1353,9 +1436,16 @@ public final class MediaCodecInfo {
Integer height = (Integer)map.get(MediaFormat.KEY_HEIGHT);
Number rate = (Number)map.get(MediaFormat.KEY_FRAME_RATE);
// we ignore color-format for now as it is not reliably reported by codec
if (!supports(width, height, rate)) {
return false;
}
return supports(width, height, rate);
if (!CodecCapabilities.supportsBitrate(mBitrateRange, format)) {
return false;
}
// we ignore color-format for now as it is not reliably reported by codec
return true;
}
/* no public constructor */

View File

@@ -185,11 +185,19 @@ public final class MediaFormat {
public static final String KEY_MAX_INPUT_SIZE = "max-input-size";
/**
* A key describing the bitrate in bits/sec.
* A key describing the average bitrate in bits/sec.
* The associated value is an integer
*/
public static final String KEY_BIT_RATE = "bitrate";
/**
* A key describing the max bitrate in bits/sec.
* This is usually over a one-second sliding window (e.g. over any window of one second).
* The associated value is an integer
* @hide
*/
public static final String KEY_MAX_BIT_RATE = "max-bitrate";
/**
* A key describing the color format of the content in a video format.
* Constants are declared in {@link android.media.MediaCodecInfo.CodecCapabilities}.