From 1de8506a0d06208304468c9abcee86eebec70828 Mon Sep 17 00:00:00 2001 From: Romain Vimont Date: Wed, 28 Mar 2018 22:02:27 +0200 Subject: [PATCH] Support Android API 19 Since "adb forward" fallback has been implemented, it is easy to support API 19. Replace the incompatible calls related to MediaCodec to use minSdkVersion 19 instead of 21. --- README.md | 2 +- server/build.gradle | 2 +- .../com/genymobile/scrcpy/ScreenEncoder.java | 16 +++++++++++++++- 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index fa55b92f..8a55173d 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ and _MacOS_. ## Requirements -The Android part requires at least API 21 (Android 5.0). +The Android part requires at least API 19 (Android 4.4). You need [adb]. It is available in the [Android SDK platform tools][platform-tools], or packaged in your distribution (`android-adb-tools`). diff --git a/server/build.gradle b/server/build.gradle index 066fe52d..5fed22be 100644 --- a/server/build.gradle +++ b/server/build.gradle @@ -4,7 +4,7 @@ android { compileSdkVersion 27 defaultConfig { applicationId "com.genymobile.scrcpy" - minSdkVersion 21 + minSdkVersion 19 targetSdkVersion 27 versionCode 2 versionName "1.1" diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index 3014397c..01c87303 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -6,6 +6,7 @@ import android.graphics.Rect; import android.media.MediaCodec; import android.media.MediaCodecInfo; import android.media.MediaFormat; +import android.os.Build; import android.os.IBinder; import android.view.Surface; @@ -77,11 +78,17 @@ public class ScreenEncoder implements Device.RotationListener { } } + @SuppressWarnings("deprecation") // Android API 19 requires to call deprecated methods private boolean encode(MediaCodec codec, OutputStream outputStream) throws IOException { @SuppressWarnings("checkstyle:MagicNumber") byte[] buf = new byte[bitRate / 8]; // may contain up to 1 second of video boolean eof = false; MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); + + ByteBuffer[] outputBuffers = null; + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { + outputBuffers = codec.getOutputBuffers(); + } while (!consumeRotationChange() && !eof) { int outputBufferId = codec.dequeueOutputBuffer(bufferInfo, -1); eof = (bufferInfo.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0; @@ -91,7 +98,12 @@ public class ScreenEncoder implements Device.RotationListener { break; } if (outputBufferId >= 0) { - ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId); + ByteBuffer outputBuffer; + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { + outputBuffer = codec.getOutputBuffer(outputBufferId); + } else { + outputBuffer = outputBuffers[outputBufferId]; + } while (outputBuffer.hasRemaining()) { int remaining = outputBuffer.remaining(); int len = Math.min(buf.length, remaining); @@ -100,6 +112,8 @@ public class ScreenEncoder implements Device.RotationListener { outputBuffer.get(buf, 0, len); outputStream.write(buf, 0, len); } + } else if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP && outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { + outputBuffers = codec.getOutputBuffers(); } } finally { if (outputBufferId >= 0) { -- GitLab