From 953ba1021f9e1112d694224fd6cc5688eeecb770 Mon Sep 17 00:00:00 2001 From: Eugen Pechanec Date: Sat, 25 Jun 2022 13:27:03 +0200 Subject: [PATCH] Extract MediaCodecListCompat from ScreenEncoder --- .../scrcpy/MediaCodecListCompat.java | 73 +++++++++++++++++++ .../com/genymobile/scrcpy/ScreenEncoder.java | 18 +---- 2 files changed, 74 insertions(+), 17 deletions(-) create mode 100644 server/src/main/java/com/genymobile/scrcpy/MediaCodecListCompat.java diff --git a/server/src/main/java/com/genymobile/scrcpy/MediaCodecListCompat.java b/server/src/main/java/com/genymobile/scrcpy/MediaCodecListCompat.java new file mode 100644 index 00000000..1b5e50eb --- /dev/null +++ b/server/src/main/java/com/genymobile/scrcpy/MediaCodecListCompat.java @@ -0,0 +1,73 @@ +package com.genymobile.scrcpy; + +import android.media.MediaCodecInfo; +import android.media.MediaCodecList; +import androidx.annotation.NonNull; +import androidx.annotation.RequiresApi; + +import java.util.Arrays; + +import static android.media.MediaCodecList.REGULAR_CODECS; +import static android.os.Build.VERSION.SDK_INT; + +/** + * Version of {@link MediaCodecList} that backports {@link #getCodecInfos()} to Kitkat. + */ +abstract class MediaCodecListCompat { + MediaCodecListCompat() { + } + + /** + * Returns the list of codecs that are suitable + * for regular (buffer-to-buffer) decoding or encoding. + */ + static MediaCodecListCompat regular() { + if (SDK_INT >= 21) { + return new Platform(); + } else { + return new Backport(); + } + } + + /** + * Returns the list of {@link MediaCodecInfo} objects for the list + * of media-codecs. + */ + @NonNull + abstract MediaCodecInfo[] getCodecInfos(); + + @SuppressWarnings("deprecation") + private static class Backport extends MediaCodecListCompat { + private final MediaCodecInfo[] mCodecInfos; + + Backport() { + final int size = MediaCodecList.getCodecCount(); + final MediaCodecInfo[] codecInfos = new MediaCodecInfo[size]; + for (int i = 0; i < size; i++) { + codecInfos[i] = MediaCodecList.getCodecInfoAt(i); + } + this.mCodecInfos = codecInfos; + } + + @NonNull + @Override + public final MediaCodecInfo[] getCodecInfos() { + return Arrays.copyOf(mCodecInfos, mCodecInfos.length); + } + } + + @RequiresApi(21) + private static class Platform extends MediaCodecListCompat { + private final MediaCodecList mDelegate; + + Platform() { + this.mDelegate = new MediaCodecList(REGULAR_CODECS); + } + + @NonNull + @Override + MediaCodecInfo[] getCodecInfos() { + return mDelegate.getCodecInfos(); + } + } +} diff --git a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java index ccdf0d1b..8381edc2 100644 --- a/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java +++ b/server/src/main/java/com/genymobile/scrcpy/ScreenEncoder.java @@ -5,7 +5,6 @@ import com.genymobile.scrcpy.wrappers.SurfaceControl; import android.graphics.Rect; import android.media.MediaCodec; import android.media.MediaCodecInfo; -import android.media.MediaCodecList; import android.media.MediaFormat; import android.os.Build; import android.os.IBinder; @@ -202,24 +201,9 @@ public class ScreenEncoder implements Device.RotationListener { IO.writeFully(fd, headerBuffer); } - @SuppressWarnings("deprecation") // Android API 19 requires to call deprecated methods - private static MediaCodecInfo[] getCodecInfosCompat() { - if (Build.VERSION.SDK_INT >= 21) { - MediaCodecList list = new MediaCodecList(MediaCodecList.REGULAR_CODECS); - return list.getCodecInfos(); - } else { - final int size = MediaCodecList.getCodecCount(); - final MediaCodecInfo[] infos = new MediaCodecInfo[size]; - for (int i = 0; i < size; i++) { - infos[i] = MediaCodecList.getCodecInfoAt(i); - } - return infos; - } - } - private static MediaCodecInfo[] listEncoders() { List result = new ArrayList<>(); - MediaCodecInfo[] codecInfos = getCodecInfosCompat(); + MediaCodecInfo[] codecInfos = MediaCodecListCompat.regular().getCodecInfos(); for (MediaCodecInfo codecInfo : codecInfos) { if (codecInfo.isEncoder() && Arrays.asList(codecInfo.getSupportedTypes()).contains(MediaFormat.MIMETYPE_VIDEO_AVC)) { result.add(codecInfo);