From e5ac17be5d2974d45301e8626d485b3a83397046 Mon Sep 17 00:00:00 2001 From: Mattia Iavarone Date: Mon, 12 Aug 2019 12:38:29 +0200 Subject: [PATCH] Create DeviceEncoders --- .../cameraview/internal/DeviceEncoders.java | 89 +++++++++++++++++++ 1 file changed, 89 insertions(+) create mode 100644 cameraview/src/main/java/com/otaliastudios/cameraview/internal/DeviceEncoders.java diff --git a/cameraview/src/main/java/com/otaliastudios/cameraview/internal/DeviceEncoders.java b/cameraview/src/main/java/com/otaliastudios/cameraview/internal/DeviceEncoders.java new file mode 100644 index 00000000..015d5ff3 --- /dev/null +++ b/cameraview/src/main/java/com/otaliastudios/cameraview/internal/DeviceEncoders.java @@ -0,0 +1,89 @@ +package com.otaliastudios.cameraview.internal; + +import android.annotation.SuppressLint; +import android.annotation.TargetApi; +import android.media.MediaCodecInfo; +import android.media.MediaCodecList; +import android.os.Build; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import java.util.ArrayList; +import java.util.List; + +/** + * Checks the capabilities of device encoders. + */ +public class DeviceEncoders { + + private final List mEncoders; + + public DeviceEncoders() { + mEncoders = getDeviceEncoders(); + } + + @Nullable + private List getDeviceEncoders() { + if (Build.VERSION.SDK_INT >= 21) { + ArrayList results = new ArrayList<>(); + MediaCodecInfo[] array = new MediaCodecList(MediaCodecList.REGULAR_CODECS).getCodecInfos(); + for (MediaCodecInfo info : array) { + if (info.isEncoder()) results.add(info); + } + return results; + } else { + // We could still get a list of MediaCodecInfo for API >= 16, but it seems that the APIs + // for querying the availability of a specified MediaFormat were only added in 21 anyway. + return null; + } + } + + @SuppressLint("NewApi") + @Nullable + private List getCapabilities(@NonNull String mimeType) { + if (mEncoders == null) return null; + ArrayList results = new ArrayList<>(); + for (MediaCodecInfo encoder : mEncoders) { + String[] types = encoder.getSupportedTypes(); + for (String type : types) { + if (type.equalsIgnoreCase(mimeType)) { + results.add(encoder.getCapabilitiesForType(type)); + break; + } + } + } + return results; + } + + @SuppressLint("NewApi") + public boolean supportsVideo(@NonNull String mimeType, int width, int height, int bitRate) { + List capabilities = getCapabilities(mimeType); + if (capabilities == null) return true; + if (capabilities.isEmpty()) return false; + for (MediaCodecInfo.CodecCapabilities cap : capabilities) { + MediaCodecInfo.VideoCapabilities videoCap = cap.getVideoCapabilities(); + if (videoCap.isSizeSupported(width, height) + && videoCap.getBitrateRange().contains(bitRate)) { + return true; + } + } + return false; + } + + @SuppressLint("NewApi") + public boolean supportsAudio(@NonNull String mimeType, int sampleRate, int bitRate) { + List capabilities = getCapabilities(mimeType); + if (capabilities == null) return true; + if (capabilities.isEmpty()) return false; + for (MediaCodecInfo.CodecCapabilities cap : capabilities) { + MediaCodecInfo.AudioCapabilities audioCap = cap.getAudioCapabilities(); + if (audioCap.isSampleRateSupported(sampleRate) + && audioCap.getBitrateRange().contains(bitRate)) { + return true; + } + } + return false; + } + +}