diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index c9a37f84..15e57b9d 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -28,18 +28,20 @@ public class ScreenEncoder implements Device.RotationListener { private int bitRate; private int maxFps; private int iFrameInterval; + private int codecProfile; private boolean sendFrameMeta; private long ptsOrigin; - public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, int iFrameInterval) { + public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, int codecProfile, int iFrameInterval) { this.sendFrameMeta = sendFrameMeta; this.bitRate = bitRate; this.maxFps = maxFps; + this.codecProfile = codecProfile; this.iFrameInterval = iFrameInterval; } - public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps) { - this(sendFrameMeta, bitRate, maxFps, DEFAULT_I_FRAME_INTERVAL); + public ScreenEncoder(boolean sendFrameMeta, int bitRate, int maxFps, int codecProfile) { + this(sendFrameMeta, bitRate, maxFps, codecProfile, DEFAULT_I_FRAME_INTERVAL); } @Override @@ -61,6 +63,7 @@ public class ScreenEncoder implements Device.RotationListener { try { do { MediaCodec codec = createCodec(); + setCodecProfile(codec, format); IBinder display = createDisplay(); Rect contentRect = device.getScreenInfo().getContentRect(); Rect videoRect = device.getScreenInfo().getVideoSize().toRect(); @@ -134,6 +137,22 @@ public class ScreenEncoder implements Device.RotationListener { IO.writeFully(fd, headerBuffer); } + private void setCodecProfile(MediaCodec codec, MediaFormat format) throws IOException { + if(codecProfile == 0) return; + int level = 0; + for (MediaCodecInfo.CodecProfileLevel profileLevel : codec.getCodecInfo().getCapabilitiesForType("video/avc").profileLevels) { + if(profileLevel.profile == codecProfile) { + level = Math.max(level, profileLevel.level); + } + } + if(level == 0) throw new IOException("Device doesn't support the requested codec profile."); + // Profile (SDK Level 21) and Level (SDK Level 23). + format.setInteger(MediaFormat.KEY_PROFILE, codecProfile); + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { + format.setInteger(MediaFormat.KEY_LEVEL, level); + } + } + private static MediaCodec createCodec() throws IOException { return MediaCodec.createEncoderByType("video/avc"); } diff --git a/server/src/main/java/com/genymobile/scrcpy/Server.java b/server/src/main/java/com/genymobile/scrcpy/Server.java index 1f3b281d..a831a6a2 100644 --- a/server/src/main/java/com/genymobile/scrcpy/Server.java +++ b/server/src/main/java/com/genymobile/scrcpy/Server.java @@ -19,7 +19,7 @@ public final class Server { final Device device = new Device(options); boolean tunnelForward = options.isTunnelForward(); try (DesktopConnection connection = DesktopConnection.open(device, tunnelForward)) { - ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps()); + ScreenEncoder screenEncoder = new ScreenEncoder(options.getSendFrameMeta(), options.getBitRate(), options.getMaxFps(), options.getCodecProfile()); if (options.getControl()) { Controller controller = new Controller(device, connection);