Merge "MediaCodecInfo: limit resolution to 4K for 32-bit processes"

This commit is contained in:
Treehugger Robot
2020-12-14 06:09:09 +00:00
committed by Gerrit Code Review

View File

@@ -25,6 +25,7 @@ import android.annotation.SuppressLint;
import android.annotation.TestApi; import android.annotation.TestApi;
import android.compat.annotation.UnsupportedAppUsage; import android.compat.annotation.UnsupportedAppUsage;
import android.os.Build; import android.os.Build;
import android.os.Process;
import android.os.SystemProperties; import android.os.SystemProperties;
import android.util.Log; import android.util.Log;
import android.util.Pair; import android.util.Pair;
@@ -188,13 +189,14 @@ public final class MediaCodecInfo {
// COMMON CONSTANTS // COMMON CONSTANTS
private static final Range<Integer> POSITIVE_INTEGERS = private static final Range<Integer> POSITIVE_INTEGERS =
Range.create(1, Integer.MAX_VALUE); Range.create(1, Integer.MAX_VALUE);
private static final Range<Long> POSITIVE_LONGS = private static final Range<Long> POSITIVE_LONGS =
Range.create(1l, Long.MAX_VALUE); Range.create(1L, Long.MAX_VALUE);
private static final Range<Rational> POSITIVE_RATIONALS = private static final Range<Rational> POSITIVE_RATIONALS =
Range.create(new Rational(1, Integer.MAX_VALUE), Range.create(new Rational(1, Integer.MAX_VALUE),
new Rational(Integer.MAX_VALUE, 1)); new Rational(Integer.MAX_VALUE, 1));
private static final Range<Integer> SIZE_RANGE = Range.create(1, 32768); private static final Range<Integer> SIZE_RANGE =
Process.is64Bit() ? Range.create(1, 32768) : Range.create(1, 4096);
private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960); private static final Range<Integer> FRAME_RATE_RANGE = Range.create(0, 960);
private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000); private static final Range<Integer> BITRATE_RANGE = Range.create(0, 500000000);
private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32; private static final int DEFAULT_MAX_SUPPORTED_INSTANCES = 32;
@@ -1399,6 +1401,9 @@ public final class MediaCodecInfo {
/** /**
* Returns the range of supported video widths. * Returns the range of supported video widths.
* <p class=note>
* 32-bit processes will not support resolutions larger than 4096x4096 due to
* the limited address space.
*/ */
public Range<Integer> getSupportedWidths() { public Range<Integer> getSupportedWidths() {
return mWidthRange; return mWidthRange;
@@ -1406,6 +1411,9 @@ public final class MediaCodecInfo {
/** /**
* Returns the range of supported video heights. * Returns the range of supported video heights.
* <p class=note>
* 32-bit processes will not support resolutions larger than 4096x4096 due to
* the limited address space.
*/ */
public Range<Integer> getSupportedHeights() { public Range<Integer> getSupportedHeights() {
return mHeightRange; return mHeightRange;
@@ -1857,6 +1865,10 @@ public final class MediaCodecInfo {
&& aligned.mMaxMacroBlockRate >= otherAligned.mMaxMacroBlockRate); && aligned.mMaxMacroBlockRate >= otherAligned.mMaxMacroBlockRate);
} }
/* package private */ boolean isEqualDimension(@NonNull PerformancePoint other) {
return mWidth == other.mWidth && mHeight == other.mHeight;
}
private @NonNull Size getCommonBlockSize(@NonNull PerformancePoint other) { private @NonNull Size getCommonBlockSize(@NonNull PerformancePoint other) {
return new Size( return new Size(
Math.max(mBlockSize.getWidth(), other.mBlockSize.getWidth()) * 16, Math.max(mBlockSize.getWidth(), other.mBlockSize.getWidth()) * 16,
@@ -1997,6 +2009,9 @@ public final class MediaCodecInfo {
* Performance points assume a single active codec. For use cases where multiple * Performance points assume a single active codec. For use cases where multiple
* codecs are active, should use that highest pixel count, and add the frame rates of * codecs are active, should use that highest pixel count, and add the frame rates of
* each individual codec. * each individual codec.
* <p class=note>
* Supported resolution could be further restricted for 32-bit processes due to
* the limited virtual memory space.
*/ */
@Nullable @Nullable
public List<PerformancePoint> getSupportedPerformancePoints() { public List<PerformancePoint> getSupportedPerformancePoints() {
@@ -2164,6 +2179,12 @@ public final class MediaCodecInfo {
if (size == null || size.getWidth() * size.getHeight() <= 0) { if (size == null || size.getWidth() * size.getHeight() <= 0) {
continue; continue;
} }
if (size.getWidth() > SIZE_RANGE.getUpper()
|| size.getHeight() > SIZE_RANGE.getUpper()) {
size = new Size(
Math.min(size.getWidth(), SIZE_RANGE.getUpper()),
Math.min(size.getHeight(), SIZE_RANGE.getUpper()));
}
Range<Long> range = Utils.parseLongRange(map.get(key), null); Range<Long> range = Utils.parseLongRange(map.get(key), null);
if (range == null || range.getLower() < 0 || range.getUpper() < 0) { if (range == null || range.getLower() < 0 || range.getUpper() < 0) {
continue; continue;
@@ -2193,6 +2214,29 @@ public final class MediaCodecInfo {
(a.getMaxMacroBlockRate() < b.getMaxMacroBlockRate() ? -1 : 1) : (a.getMaxMacroBlockRate() < b.getMaxMacroBlockRate() ? -1 : 1) :
(a.getMaxFrameRate() != b.getMaxFrameRate()) ? (a.getMaxFrameRate() != b.getMaxFrameRate()) ?
(a.getMaxFrameRate() < b.getMaxFrameRate() ? -1 : 1) : 0)); (a.getMaxFrameRate() < b.getMaxFrameRate() ? -1 : 1) : 0));
// remove redundant points
for (int i = 1; i < ret.size(); ++i) {
PerformancePoint a = ret.get(i);
for (int j = 0; j < i; ++j) {
PerformancePoint b = ret.get(j);
if (b.isEqualDimension(a) && b.covers(a)) {
ret.set(i, null);
break;
}
}
}
int newSize = 0;
for (int i = 0; i < ret.size(); ++i) {
PerformancePoint a = ret.get(i);
if (a == null) {
continue;
}
ret.set(newSize, a);
++newSize;
}
ret.setSize(newSize);
return Collections.unmodifiableList(ret); return Collections.unmodifiableList(ret);
} }