Simplify DeviceEncoders class

pull/588/head
Mattia Iavarone 6 years ago
parent 470c53c2ba
commit f1b29a0c48
  1. 8
      cameraview/src/androidTest/java/com/otaliastudios/cameraview/internal/DeviceEncodersTest.java
  2. 31
      cameraview/src/main/java/com/otaliastudios/cameraview/internal/DeviceEncoders.java
  3. 4
      cameraview/src/main/java/com/otaliastudios/cameraview/video/FullVideoRecorder.java
  4. 5
      cameraview/src/main/java/com/otaliastudios/cameraview/video/SnapshotVideoRecorder.java

@ -13,7 +13,6 @@ import com.otaliastudios.cameraview.size.Size;
import org.junit.After; import org.junit.After;
import org.junit.Before; import org.junit.Before;
import org.junit.Rule;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
@ -50,10 +49,11 @@ public class DeviceEncodersTest extends BaseTest {
@NonNull @NonNull
private DeviceEncoders create() { private DeviceEncoders create() {
return new DeviceEncoders( return new DeviceEncoders(DeviceEncoders.MODE_RESPECT_ORDER,
"video/avc", "video/avc",
"audio/mp4a-latm", "audio/mp4a-latm",
DeviceEncoders.MODE_TAKE_FIRST); 0,
0);
} }
@Test @Test
@ -82,7 +82,7 @@ public class DeviceEncodersTest extends BaseTest {
if (DeviceEncoders.ENABLED) { if (DeviceEncoders.ENABLED) {
List<MediaCodecInfo> allEncoders = deviceEncoders.getDeviceEncoders(); List<MediaCodecInfo> allEncoders = deviceEncoders.getDeviceEncoders();
MediaCodecInfo encoder = deviceEncoders.findDeviceEncoder(allEncoders, MediaCodecInfo encoder = deviceEncoders.findDeviceEncoder(allEncoders,
"video/avc", DeviceEncoders.MODE_TAKE_FIRST, 0); "video/avc", DeviceEncoders.MODE_RESPECT_ORDER, 0);
assertNotNull(encoder); assertNotNull(encoder);
List<String> encoderTypes = Arrays.asList(encoder.getSupportedTypes()); List<String> encoderTypes = Arrays.asList(encoder.getSupportedTypes());
assertTrue(encoderTypes.contains("video/avc")); assertTrue(encoderTypes.contains("video/avc"));

@ -20,9 +20,18 @@ import java.util.List;
/** /**
* Checks the capabilities of device encoders and adjust parameters to ensure * Checks the capabilities of device encoders and adjust parameters to ensure
* that they'll be supported by the final encoder. * that they'll be supported by the final encoder.
* This can choose the encoder in two ways, based on the mode flag:
* *
* 1. {@link #MODE_TAKE_FIRST} * Methods in this class might throw either a {@link VideoException} or a {@link AudioException}.
* Throwing this exception means that the given parameters will not be supported by the encoder
* for that type, and cannot be tweaked to be.
*
* When this happens, users should retry with a new {@link DeviceEncoders} instance, but with
* the audio or video encoder offset incremented. This offset is the position in the encoder list
* from which we'll choose the potential encoder.
*
* This class will inspect the encoders list in two ways, based on the mode flag:
*
* 1. {@link #MODE_RESPECT_ORDER}
* *
* Chooses the encoder as the first one that matches the given mime type. * Chooses the encoder as the first one that matches the given mime type.
* This is what {@link android.media.MediaCodec#createEncoderByType(String)} does, * This is what {@link android.media.MediaCodec#createEncoderByType(String)} does,
@ -40,11 +49,12 @@ import java.util.List;
* - MediaCodecList (https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/MediaCodecList.cpp#322) * - MediaCodecList (https://android.googlesource.com/platform/frameworks/av/+/master/media/libstagefright/MediaCodecList.cpp#322)
* *
* To be fair, what {@link android.media.MediaRecorder} does is actually choose the first one * To be fair, what {@link android.media.MediaRecorder} does is actually choose the first one
* that configures itself without errors. We currently do not offer this option here. TODO * that configures itself without errors. We currently do not offer this option here.
* TODO add a tryConfigure() step, that throws AudioException/VideoException ?
* *
* 2. {@link #MODE_PREFER_HARDWARE} * 2. {@link #MODE_PREFER_HARDWARE}
* *
* This takes the list - as ordered by the vendor - and just sorts it such that hardware encoders * This takes the list - as ordered by the vendor - and just sorts it so that hardware encoders
* are preferred over software ones. It's questionable whether this is good or not. Some vendors * are preferred over software ones. It's questionable whether this is good or not. Some vendors
* might forget to put hardware encoders first in the list, some others might put poor hardware * might forget to put hardware encoders first in the list, some others might put poor hardware
* encoders on the bottom of the list on purpose. * encoders on the bottom of the list on purpose.
@ -56,7 +66,7 @@ public class DeviceEncoders {
@VisibleForTesting static boolean ENABLED = Build.VERSION.SDK_INT >= 21; @VisibleForTesting static boolean ENABLED = Build.VERSION.SDK_INT >= 21;
public final static int MODE_TAKE_FIRST = 0; public final static int MODE_RESPECT_ORDER = 0;
public final static int MODE_PREFER_HARDWARE = 1; public final static int MODE_PREFER_HARDWARE = 1;
/** /**
@ -87,14 +97,9 @@ public class DeviceEncoders {
private final MediaCodecInfo.AudioCapabilities mAudioCapabilities; private final MediaCodecInfo.AudioCapabilities mAudioCapabilities;
@SuppressLint("NewApi") @SuppressLint("NewApi")
public DeviceEncoders(@NonNull String videoType, @NonNull String audioType, int mode) { public DeviceEncoders(int mode,
this(videoType, audioType, mode, 0, 0); @NonNull String videoType,
}
@SuppressLint("NewApi")
public DeviceEncoders(@NonNull String videoType,
@NonNull String audioType, @NonNull String audioType,
int mode,
int videoOffset, int videoOffset,
int audioOffset) { int audioOffset) {
// We could still get a list of MediaCodecInfo for API >= 16, but it seems that the APIs // We could still get a list of MediaCodecInfo for API >= 16, but it seems that the APIs
@ -154,7 +159,7 @@ public class DeviceEncoders {
/** /**
* Finds the encoder we'll be using, depending on the given mode flag: * Finds the encoder we'll be using, depending on the given mode flag:
* - {@link #MODE_TAKE_FIRST} will just take the first of the list * - {@link #MODE_RESPECT_ORDER} will just take the first of the list
* - {@link #MODE_PREFER_HARDWARE} will prefer hardware encoders * - {@link #MODE_PREFER_HARDWARE} will prefer hardware encoders
* Throws if we find no encoder for this type. * Throws if we find no encoder for this type.
* *

@ -111,8 +111,8 @@ public abstract class FullVideoRecorder extends VideoRecorder {
int audioEncoderOffset = 0; int audioEncoderOffset = 0;
boolean encodersFound = false; boolean encodersFound = false;
while (!encodersFound) { while (!encodersFound) {
DeviceEncoders encoders = new DeviceEncoders(videoType, audioType, DeviceEncoders encoders = new DeviceEncoders(DeviceEncoders.MODE_RESPECT_ORDER,
DeviceEncoders.MODE_TAKE_FIRST, videoEncoderOffset, audioEncoderOffset); videoType, audioType, videoEncoderOffset, audioEncoderOffset);
try { try {
newVideoSize = encoders.getSupportedVideoSize(stub.size); newVideoSize = encoders.getSupportedVideoSize(stub.size);
newVideoBitRate = encoders.getSupportedVideoBitRate(stub.videoBitRate); newVideoBitRate = encoders.getSupportedVideoBitRate(stub.videoBitRate);

@ -145,9 +145,8 @@ public class SnapshotVideoRecorder extends VideoRecorder implements RendererFram
boolean encodersFound = false; boolean encodersFound = false;
DeviceEncoders deviceEncoders = null; DeviceEncoders deviceEncoders = null;
while (!encodersFound) { while (!encodersFound) {
deviceEncoders = new DeviceEncoders(videoType, audioType, deviceEncoders = new DeviceEncoders(DeviceEncoders.MODE_PREFER_HARDWARE,
DeviceEncoders.MODE_PREFER_HARDWARE, videoEncoderOffset, videoType, audioType, videoEncoderOffset, audioEncoderOffset);
audioEncoderOffset);
try { try {
newVideoSize = deviceEncoders.getSupportedVideoSize(mResult.size); newVideoSize = deviceEncoders.getSupportedVideoSize(mResult.size);
newVideoBitRate = deviceEncoders.getSupportedVideoBitRate(mResult.videoBitRate); newVideoBitRate = deviceEncoders.getSupportedVideoBitRate(mResult.videoBitRate);

Loading…
Cancel
Save