From 89aa7b649aeb0e8ce996b5c0110d00d7656a79f5 Mon Sep 17 00:00:00 2001 From: Tzah Mazuz Date: Thu, 12 Mar 2020 16:56:27 +0200 Subject: [PATCH] Adding codecProfile and setCodecProfile to the ScreenEncoder (cherry picked from commit db14945a119655c7775f480839983b615effbf2d) --- .../com/genymobile/scrcpy/ScreenEncoder.java | 25 ++++++++++++++++--- .../java/com/genymobile/scrcpy/Server.java | 2 +- 2 files changed, 23 insertions(+), 4 deletions(-) diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index c9a37f847b..15e57b9d75 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 void streamScreen(Device device, FileDescriptor fd) throws IOException { 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 @@ private void writeFrameMeta(FileDescriptor fd, MediaCodec.BufferInfo bufferInfo, 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 1f3b281d1c..a831a6a23f 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 @@ private static void scrcpy(Options options) throws IOException { 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);