mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Apply resolution fix.
Some devices under report their resolution support, like 2144 for 2160 in H265, 1072 for 1080 in H264. This CL only takes care of these two cases, - reporting 1920x1080 is supported when the device reports 1920x1072, and - reporting 3840x2160 is supported when the device reports 3840x2144 PiperOrigin-RevId: 443095042
This commit is contained in:
parent
63052e1a7c
commit
f903e4a9f8
@ -256,8 +256,9 @@ public final class AndroidTestUtil {
|
||||
if (decoderInfo == null) {
|
||||
return false;
|
||||
}
|
||||
// Use Format.NO_VALUE for frame rate to only check whether size is supported.
|
||||
return decoderInfo.isVideoSizeAndRateSupportedV21(
|
||||
format.width, format.height, format.frameRate);
|
||||
format.width, format.height, /* frameRate= */ Format.NO_VALUE);
|
||||
}
|
||||
|
||||
private static boolean canEncode(Format format) {
|
||||
@ -267,8 +268,8 @@ public final class AndroidTestUtil {
|
||||
if (supportedEncoders.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
return EncoderUtil.areSizeAndRateSupported(
|
||||
supportedEncoders.get(0), mimeType, format.width, format.height, format.frameRate);
|
||||
return EncoderUtil.isSizeSupported(
|
||||
supportedEncoders.get(0), mimeType, format.width, format.height);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -20,6 +20,7 @@ import static androidx.media3.common.util.Assertions.checkNotNull;
|
||||
import static java.lang.Math.max;
|
||||
import static java.lang.Math.round;
|
||||
|
||||
import android.media.CamcorderProfile;
|
||||
import android.media.MediaCodec;
|
||||
import android.media.MediaCodecInfo;
|
||||
import android.media.MediaCodecList;
|
||||
@ -66,24 +67,27 @@ public final class EncoderUtil {
|
||||
return checkNotNull(MIME_TYPE_TO_ENCODERS.get()).keySet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the {@linkplain MediaCodecInfo encoder} supports the given resolution and frame
|
||||
* rate.
|
||||
*/
|
||||
public static boolean areSizeAndRateSupported(
|
||||
MediaCodecInfo encoderInfo, String mimeType, int width, int height, double frameRate) {
|
||||
// VideoCapabilities.areSizeAndRateSupported incorrectly returns false if frameRate < 1 on all
|
||||
// current versions of Android, so only checks the width and height in this case [b/153940404].
|
||||
if (frameRate == Format.NO_VALUE || frameRate < 1) {
|
||||
return encoderInfo
|
||||
.getCapabilitiesForType(mimeType)
|
||||
.getVideoCapabilities()
|
||||
.isSizeSupported(width, height);
|
||||
}
|
||||
return encoderInfo
|
||||
/** Returns whether the {@linkplain MediaCodecInfo encoder} supports the given resolution. */
|
||||
public static boolean isSizeSupported(
|
||||
MediaCodecInfo encoderInfo, String mimeType, int width, int height) {
|
||||
if (encoderInfo
|
||||
.getCapabilitiesForType(mimeType)
|
||||
.getVideoCapabilities()
|
||||
.areSizeAndRateSupported(width, height, frameRate);
|
||||
.isSizeSupported(width, height)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Some devices (Samsung, Huawei, and Pixel 6. See b/222095724) under-report their encoding
|
||||
// capabilities. The supported height reported for H265@3840x2160 is 2144, and
|
||||
// H264@1920x1080 is 1072. See b/229825948.
|
||||
// Cross reference with CamcorderProfile to ensure a resolution is supported.
|
||||
if (width == 1920 && height == 1080) {
|
||||
return CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_1080P);
|
||||
}
|
||||
if (width == 3840 && height == 2160) {
|
||||
return CamcorderProfile.hasProfile(CamcorderProfile.QUALITY_2160P);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -142,35 +146,35 @@ public final class EncoderUtil {
|
||||
// Fix size alignment.
|
||||
width = alignResolution(width, widthAlignment);
|
||||
height = alignResolution(height, heightAlignment);
|
||||
if (videoEncoderCapabilities.isSizeSupported(width, height)) {
|
||||
if (isSizeSupported(encoderInfo, mimeType, width, height)) {
|
||||
return new Size(width, height);
|
||||
}
|
||||
|
||||
// Try three-fourths (e.g. 1440 -> 1080).
|
||||
int newWidth = alignResolution(width * 3 / 4, widthAlignment);
|
||||
int newHeight = alignResolution(height * 3 / 4, heightAlignment);
|
||||
if (videoEncoderCapabilities.isSizeSupported(newWidth, newHeight)) {
|
||||
if (isSizeSupported(encoderInfo, mimeType, newWidth, newHeight)) {
|
||||
return new Size(newWidth, newHeight);
|
||||
}
|
||||
|
||||
// Try two-thirds (e.g. 4k -> 1440).
|
||||
newWidth = alignResolution(width * 2 / 3, widthAlignment);
|
||||
newHeight = alignResolution(height * 2 / 3, heightAlignment);
|
||||
if (videoEncoderCapabilities.isSizeSupported(newWidth, newHeight)) {
|
||||
if (isSizeSupported(encoderInfo, mimeType, width, height)) {
|
||||
return new Size(newWidth, newHeight);
|
||||
}
|
||||
|
||||
// Try half (e.g. 4k -> 1080).
|
||||
newWidth = alignResolution(width / 2, widthAlignment);
|
||||
newHeight = alignResolution(height / 2, heightAlignment);
|
||||
if (videoEncoderCapabilities.isSizeSupported(newWidth, newHeight)) {
|
||||
if (isSizeSupported(encoderInfo, mimeType, newWidth, newHeight)) {
|
||||
return new Size(newWidth, newHeight);
|
||||
}
|
||||
|
||||
// Try one-third (e.g. 4k -> 720).
|
||||
newWidth = alignResolution(width / 3, widthAlignment);
|
||||
newHeight = alignResolution(height / 3, heightAlignment);
|
||||
if (videoEncoderCapabilities.isSizeSupported(newWidth, newHeight)) {
|
||||
if (isSizeSupported(encoderInfo, mimeType, newWidth, newHeight)) {
|
||||
return new Size(newWidth, newHeight);
|
||||
}
|
||||
|
||||
@ -183,7 +187,7 @@ public final class EncoderUtil {
|
||||
height = alignResolution(adjustedHeight, heightAlignment);
|
||||
}
|
||||
|
||||
return videoEncoderCapabilities.isSizeSupported(width, height) ? new Size(width, height) : null;
|
||||
return isSizeSupported(encoderInfo, mimeType, width, height) ? new Size(width, height) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user