Merge "Use decoder values for screen recording size" into sc-qpr1-dev am: 76d42927ab

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/15901815

Change-Id: I2c1c8aa45099efc6ff76c0bd7a284853c875966a
This commit is contained in:
Beth Thibodeau
2021-09-27 16:13:05 +00:00
committed by Automerger Merge Worker

View File

@@ -29,8 +29,8 @@ import android.content.Context;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.hardware.display.DisplayManager; import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay; import android.hardware.display.VirtualDisplay;
import android.media.MediaCodec;
import android.media.MediaCodecInfo; import android.media.MediaCodecInfo;
import android.media.MediaCodecList;
import android.media.MediaFormat; import android.media.MediaFormat;
import android.media.MediaMuxer; import android.media.MediaMuxer;
import android.media.MediaRecorder; import android.media.MediaRecorder;
@@ -187,77 +187,63 @@ public class ScreenMediaRecorder {
* @param refreshRate Desired refresh rate * @param refreshRate Desired refresh rate
* @return array with supported width, height, and refresh rate * @return array with supported width, height, and refresh rate
*/ */
private int[] getSupportedSize(final int screenWidth, final int screenHeight, int refreshRate) { private int[] getSupportedSize(final int screenWidth, final int screenHeight, int refreshRate)
double maxScale = 0; throws IOException {
String videoType = MediaFormat.MIMETYPE_VIDEO_AVC;
MediaCodecList codecList = new MediaCodecList(MediaCodecList.REGULAR_CODECS); // Get max size from the decoder, to ensure recordings will be playable on device
MediaCodecInfo.VideoCapabilities maxInfo = null; MediaCodec decoder = MediaCodec.createDecoderByType(videoType);
for (MediaCodecInfo codec : codecList.getCodecInfos()) { MediaCodecInfo.VideoCapabilities vc = decoder.getCodecInfo()
String videoType = MediaFormat.MIMETYPE_VIDEO_AVC; .getCapabilitiesForType(videoType).getVideoCapabilities();
String[] types = codec.getSupportedTypes(); decoder.release();
for (String t : types) {
if (!t.equalsIgnoreCase(videoType)) {
continue;
}
MediaCodecInfo.CodecCapabilities capabilities =
codec.getCapabilitiesForType(videoType);
if (capabilities != null && capabilities.getVideoCapabilities() != null) {
MediaCodecInfo.VideoCapabilities vc = capabilities.getVideoCapabilities();
int width = vc.getSupportedWidths().getUpper(); // Check if we can support screen size as-is
int height = vc.getSupportedHeights().getUpper(); int width = vc.getSupportedWidths().getUpper();
int height = vc.getSupportedHeights().getUpper();
int screenWidthAligned = screenWidth; int screenWidthAligned = screenWidth;
if (screenWidthAligned % vc.getWidthAlignment() != 0) { if (screenWidthAligned % vc.getWidthAlignment() != 0) {
screenWidthAligned -= (screenWidthAligned % vc.getWidthAlignment()); screenWidthAligned -= (screenWidthAligned % vc.getWidthAlignment());
} }
int screenHeightAligned = screenHeight; int screenHeightAligned = screenHeight;
if (screenHeightAligned % vc.getHeightAlignment() != 0) { if (screenHeightAligned % vc.getHeightAlignment() != 0) {
screenHeightAligned -= (screenHeightAligned % vc.getHeightAlignment()); screenHeightAligned -= (screenHeightAligned % vc.getHeightAlignment());
} }
if (width >= screenWidthAligned && height >= screenHeightAligned if (width >= screenWidthAligned && height >= screenHeightAligned
&& vc.isSizeSupported(screenWidthAligned, screenHeightAligned)) { && vc.isSizeSupported(screenWidthAligned, screenHeightAligned)) {
// Desired size is supported, now get the rate // Desired size is supported, now get the rate
int maxRate = vc.getSupportedFrameRatesFor(screenWidthAligned, int maxRate = vc.getSupportedFrameRatesFor(screenWidthAligned,
screenHeightAligned).getUpper().intValue(); screenHeightAligned).getUpper().intValue();
if (maxRate < refreshRate) { if (maxRate < refreshRate) {
refreshRate = maxRate; refreshRate = maxRate;
}
Log.d(TAG, "Screen size supported at rate " + refreshRate);
return new int[]{screenWidthAligned, screenHeightAligned, refreshRate};
}
// Otherwise, continue searching
double scale = Math.min(((double) width / screenWidth),
((double) height / screenHeight));
if (scale > maxScale) {
maxScale = Math.min(1, scale);
maxInfo = vc;
}
}
} }
Log.d(TAG, "Screen size supported at rate " + refreshRate);
return new int[]{screenWidthAligned, screenHeightAligned, refreshRate};
} }
// Resize for max supported size // Otherwise, resize for max supported size
int scaledWidth = (int) (screenWidth * maxScale); double scale = Math.min(((double) width / screenWidth),
int scaledHeight = (int) (screenHeight * maxScale); ((double) height / screenHeight));
if (scaledWidth % maxInfo.getWidthAlignment() != 0) {
scaledWidth -= (scaledWidth % maxInfo.getWidthAlignment()); int scaledWidth = (int) (screenWidth * scale);
int scaledHeight = (int) (screenHeight * scale);
if (scaledWidth % vc.getWidthAlignment() != 0) {
scaledWidth -= (scaledWidth % vc.getWidthAlignment());
} }
if (scaledHeight % maxInfo.getHeightAlignment() != 0) { if (scaledHeight % vc.getHeightAlignment() != 0) {
scaledHeight -= (scaledHeight % maxInfo.getHeightAlignment()); scaledHeight -= (scaledHeight % vc.getHeightAlignment());
} }
// Find max supported rate for size // Find max supported rate for size
int maxRate = maxInfo.getSupportedFrameRatesFor(scaledWidth, scaledHeight) int maxRate = vc.getSupportedFrameRatesFor(scaledWidth, scaledHeight)
.getUpper().intValue(); .getUpper().intValue();
if (maxRate < refreshRate) { if (maxRate < refreshRate) {
refreshRate = maxRate; refreshRate = maxRate;
} }
Log.d(TAG, "Resized by " + maxScale + ": " + scaledWidth + ", " + scaledHeight Log.d(TAG, "Resized by " + scale + ": " + scaledWidth + ", " + scaledHeight
+ ", " + refreshRate); + ", " + refreshRate);
return new int[]{scaledWidth, scaledHeight, refreshRate}; return new int[]{scaledWidth, scaledHeight, refreshRate};
} }