diff --git a/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultEncoderFactory.java b/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultEncoderFactory.java index 9fe038957b..7af2582486 100644 --- a/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultEncoderFactory.java +++ b/libraries/transformer/src/main/java/androidx/media3/transformer/DefaultEncoderFactory.java @@ -18,7 +18,6 @@ package androidx.media3.transformer; import static androidx.media3.common.util.Assertions.checkArgument; import static androidx.media3.common.util.Assertions.checkNotNull; -import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Assertions.checkStateNotNull; import static androidx.media3.common.util.Util.SDK_INT; import static androidx.media3.transformer.CodecFactoryUtil.createCodec; @@ -41,22 +40,32 @@ import org.checkerframework.checker.nullness.qual.RequiresNonNull; /** A default implementation of {@link Codec.EncoderFactory}. */ @UnstableApi public final class DefaultEncoderFactory implements Codec.EncoderFactory { - // TODO(b/214973843): Add option to disable fallback. private static final int DEFAULT_COLOR_FORMAT = MediaCodecInfo.CodecCapabilities.COLOR_FormatSurface; private static final int DEFAULT_FRAME_RATE = 60; private static final int DEFAULT_I_FRAME_INTERVAL_SECS = 1; @Nullable private final EncoderSelector videoEncoderSelector; + private final boolean disableFallback; - /** Creates a new instance using the {@link EncoderSelector#DEFAULT default encoder selector}. */ + /** + * Creates a new instance using the {@link EncoderSelector#DEFAULT default encoder selector}, and + * format fallback enabled. + * + *

With format fallback enabled, and when the requested {@link Format} is not supported, {@code + * DefaultEncoderFactory} finds a format that is supported by the device and configures the {@link + * Codec} with it. The fallback process may change the requested {@link Format#sampleMimeType MIME + * type}, resolution, {@link Format#bitrate bitrate}, {@link Format#codecs profile/level}, etc. + */ public DefaultEncoderFactory() { - this(EncoderSelector.DEFAULT); + this(EncoderSelector.DEFAULT, /* disableFallback= */ false); } /** Creates a new instance. */ - public DefaultEncoderFactory(EncoderSelector videoEncoderSelector) { + public DefaultEncoderFactory( + @Nullable EncoderSelector videoEncoderSelector, boolean disableFallback) { this.videoEncoderSelector = videoEncoderSelector; + this.disableFallback = disableFallback; } @Override @@ -98,7 +107,8 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory { @Nullable Pair encoderAndClosestFormatSupport = - findEncoderWithClosestFormatSupport(format, videoEncoderSelector, allowedMimeTypes); + findEncoderWithClosestFormatSupport( + format, videoEncoderSelector, allowedMimeTypes, disableFallback); if (encoderAndClosestFormatSupport == null) { throw createTransformationException( new IllegalArgumentException( @@ -145,16 +155,24 @@ public final class DefaultEncoderFactory implements Codec.EncoderFactory { @RequiresNonNull("#1.sampleMimeType") @Nullable private static Pair findEncoderWithClosestFormatSupport( - Format requestedFormat, EncoderSelector encoderSelector, List allowedMimeTypes) { + Format requestedFormat, + EncoderSelector encoderSelector, + List allowedMimeTypes, + boolean disableFallback) { + String requestedMimeType = requestedFormat.sampleMimeType; @Nullable - String mimeType = - findFallbackMimeType(encoderSelector, requestedFormat.sampleMimeType, allowedMimeTypes); - if (mimeType == null) { + String mimeType = findFallbackMimeType(encoderSelector, requestedMimeType, allowedMimeTypes); + if (mimeType == null || (disableFallback && !requestedMimeType.equals(mimeType))) { return null; } List encodersForMimeType = encoderSelector.selectEncoderInfos(mimeType); - checkState(!encodersForMimeType.isEmpty()); + if (encodersForMimeType.isEmpty()) { + return null; + } + if (disableFallback) { + return Pair.create(encodersForMimeType.get(0), requestedFormat); + } ImmutableList filteredEncoders = filterEncoders( encodersForMimeType,