diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java index 3d6404a8ec..83a37c55db 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DecoderAudioRenderer.java @@ -19,6 +19,7 @@ import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_DR import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED; import static androidx.media3.exoplayer.DecoderReuseEvaluation.REUSE_RESULT_NO; import static androidx.media3.exoplayer.source.SampleStream.FLAG_REQUIRE_FORMAT; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.Math.max; import android.os.Handler; @@ -57,7 +58,6 @@ import androidx.media3.exoplayer.audio.AudioSink.SinkFormatSupport; import androidx.media3.exoplayer.drm.DrmSession; import androidx.media3.exoplayer.drm.DrmSession.DrmSessionException; import androidx.media3.exoplayer.source.SampleStream.ReadDataResult; -import com.google.common.base.MoreObjects; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -167,22 +167,22 @@ public abstract class DecoderAudioRenderer< * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be * null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required. - * @param audioCapabilities The audio capabilities for playback on this device. May be null if the - * default capabilities (no encoded audio passthrough support) should be assumed. + * @param audioCapabilities The audio capabilities for playback on this device. Use {@link + * AudioCapabilities#DEFAULT_AUDIO_CAPABILITIES} if default capabilities (no encoded audio + * passthrough support) should be assumed. * @param audioProcessors Optional {@link AudioProcessor}s that will process audio before output. */ public DecoderAudioRenderer( @Nullable Handler eventHandler, @Nullable AudioRendererEventListener eventListener, - @Nullable AudioCapabilities audioCapabilities, + AudioCapabilities audioCapabilities, AudioProcessor... audioProcessors) { this( eventHandler, eventListener, new DefaultAudioSink.Builder() - .setAudioCapabilities( - MoreObjects.firstNonNull( - audioCapabilities, AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES)) + .setAudioCapabilities( // For backward compatibility, null == default. + firstNonNull(audioCapabilities, AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES)) .setAudioProcessors(audioProcessors) .build()); } diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index ad0d762245..8c45a6347b 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -16,6 +16,8 @@ package androidx.media3.exoplayer.audio; import static androidx.media3.common.util.Assertions.checkNotNull; +import static androidx.media3.exoplayer.audio.AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.Math.max; import static java.lang.Math.min; @@ -219,7 +221,7 @@ public final class DefaultAudioSink implements AudioSink { /** A builder to create {@link DefaultAudioSink} instances. */ public static final class Builder { - @Nullable private AudioCapabilities audioCapabilities; + private AudioCapabilities audioCapabilities; @Nullable private AudioProcessorChain audioProcessorChain; private boolean enableFloatOutput; private boolean enableAudioTrackPlaybackParams; @@ -227,6 +229,7 @@ public final class DefaultAudioSink implements AudioSink { /** Creates a new builder. */ public Builder() { + audioCapabilities = DEFAULT_AUDIO_CAPABILITIES; offloadMode = OFFLOAD_MODE_DISABLED; } @@ -234,9 +237,10 @@ public final class DefaultAudioSink implements AudioSink { * Sets audio capabilities for playback on this device. May be {@code null} if the default * capabilities (no encoded audio passthrough support) should be assumed. * - *

The default value is {@code null}. + *

Default is {@link AudioCapabilities#DEFAULT_AUDIO_CAPABILITIES}. */ - public Builder setAudioCapabilities(@Nullable AudioCapabilities audioCapabilities) { + public Builder setAudioCapabilities(AudioCapabilities audioCapabilities) { + checkNotNull(audioCapabilities); this.audioCapabilities = audioCapabilities; return this; } @@ -422,7 +426,7 @@ public final class DefaultAudioSink implements AudioSink { */ public static boolean failOnSpuriousAudioTimestamp = false; - @Nullable private final AudioCapabilities audioCapabilities; + private final AudioCapabilities audioCapabilities; private final AudioProcessorChain audioProcessorChain; private final boolean enableFloatOutput; private final ChannelMappingAudioProcessor channelMappingAudioProcessor; @@ -495,7 +499,10 @@ public final class DefaultAudioSink implements AudioSink { imports = "androidx.media3.exoplayer.audio.DefaultAudioSink") public DefaultAudioSink( @Nullable AudioCapabilities audioCapabilities, AudioProcessor[] audioProcessors) { - this(new Builder().setAudioCapabilities(audioCapabilities).setAudioProcessors(audioProcessors)); + this( + new Builder() + .setAudioCapabilities(firstNonNull(audioCapabilities, DEFAULT_AUDIO_CAPABILITIES)) + .setAudioProcessors(audioProcessors)); } /** @deprecated Use {@link Builder}. */ @@ -515,7 +522,7 @@ public final class DefaultAudioSink implements AudioSink { boolean enableFloatOutput) { this( new Builder() - .setAudioCapabilities(audioCapabilities) + .setAudioCapabilities(firstNonNull(audioCapabilities, DEFAULT_AUDIO_CAPABILITIES)) .setAudioProcessors(audioProcessors) .setEnableFloatOutput(enableFloatOutput)); } @@ -541,7 +548,7 @@ public final class DefaultAudioSink implements AudioSink { @OffloadMode int offloadMode) { this( new Builder() - .setAudioCapabilities(audioCapabilities) + .setAudioCapabilities(firstNonNull(audioCapabilities, DEFAULT_AUDIO_CAPABILITIES)) .setAudioProcessorChain(audioProcessorChain) .setEnableFloatOutput(enableFloatOutput) .setEnableAudioTrackPlaybackParams(enableAudioTrackPlaybackParams) @@ -1601,7 +1608,7 @@ public final class DefaultAudioSink implements AudioSink { } private static boolean isPassthroughPlaybackSupported( - Format format, @Nullable AudioCapabilities audioCapabilities) { + Format format, AudioCapabilities audioCapabilities) { return getEncodingAndChannelConfigForPassthrough(format, audioCapabilities) != null; } @@ -1617,11 +1624,7 @@ public final class DefaultAudioSink implements AudioSink { */ @Nullable private static Pair getEncodingAndChannelConfigForPassthrough( - Format format, @Nullable AudioCapabilities audioCapabilities) { - if (audioCapabilities == null) { - return null; - } - + Format format, AudioCapabilities audioCapabilities) { @C.Encoding int encoding = MimeTypes.getEncoding(checkNotNull(format.sampleMimeType), format.codecs); // Check for encodings that are known to work for passthrough with the implementation in this diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java index 87f0ab1200..04d098cef1 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/MediaCodecAudioRenderer.java @@ -18,6 +18,7 @@ package androidx.media3.exoplayer.audio; import static androidx.media3.common.util.Assertions.checkNotNull; import static androidx.media3.exoplayer.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED; import static androidx.media3.exoplayer.DecoderReuseEvaluation.REUSE_RESULT_NO; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.Math.max; import android.annotation.SuppressLint; @@ -133,7 +134,12 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media MediaCodecSelector mediaCodecSelector, @Nullable Handler eventHandler, @Nullable AudioRendererEventListener eventListener) { - this(context, mediaCodecSelector, eventHandler, eventListener, (AudioCapabilities) null); + this( + context, + mediaCodecSelector, + eventHandler, + eventListener, + AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES); } /** @@ -142,8 +148,9 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media * @param eventHandler A handler to use when delivering events to {@code eventListener}. May be * null if delivery of events is not required. * @param eventListener A listener of events. May be null if delivery of events is not required. - * @param audioCapabilities The audio capabilities for playback on this device. May be null if the - * default capabilities (no encoded audio passthrough support) should be assumed. + * @param audioCapabilities The audio capabilities for playback on this device. Use {@link + * AudioCapabilities#DEFAULT_AUDIO_CAPABILITIES} if default capabilities (no encoded audio + * passthrough support) should be assumed. * @param audioProcessors Optional {@link AudioProcessor}s that will process PCM audio before * output. */ @@ -152,7 +159,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media MediaCodecSelector mediaCodecSelector, @Nullable Handler eventHandler, @Nullable AudioRendererEventListener eventListener, - @Nullable AudioCapabilities audioCapabilities, + AudioCapabilities audioCapabilities, AudioProcessor... audioProcessors) { this( context, @@ -160,7 +167,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media eventHandler, eventListener, new DefaultAudioSink.Builder() - .setAudioCapabilities(audioCapabilities) + .setAudioCapabilities( // For backward compatibility, null == default. + firstNonNull(audioCapabilities, AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES)) .setAudioProcessors(audioProcessors) .build()); } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioSinkTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioSinkTest.java index 42676641fc..4b36260424 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioSinkTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioSinkTest.java @@ -15,7 +15,6 @@ */ package androidx.media3.exoplayer.audio; -import static androidx.media3.exoplayer.audio.AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES; import static androidx.media3.exoplayer.audio.AudioSink.CURRENT_POSITION_NOT_SET; import static androidx.media3.exoplayer.audio.AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY; import static androidx.media3.exoplayer.audio.AudioSink.SINK_FORMAT_SUPPORTED_WITH_TRANSCODING; @@ -61,7 +60,6 @@ public final class DefaultAudioSinkTest { TeeAudioProcessor teeAudioProcessor = new TeeAudioProcessor(arrayAudioBufferSink); defaultAudioSink = new DefaultAudioSink.Builder() - .setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES) .setAudioProcessorChain(new DefaultAudioProcessorChain(teeAudioProcessor)) .setOffloadMode(DefaultAudioSink.OFFLOAD_MODE_DISABLED) .build(); @@ -70,10 +68,7 @@ public final class DefaultAudioSinkTest { @Test public void handlesSpecializedAudioProcessorArray() { defaultAudioSink = - new DefaultAudioSink.Builder() - .setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES) - .setAudioProcessors(new TeeAudioProcessor[0]) - .build(); + new DefaultAudioSink.Builder().setAudioProcessors(new TeeAudioProcessor[0]).build(); } @Test @@ -204,8 +199,7 @@ public final class DefaultAudioSinkTest { @Test public void floatPcmNeedsTranscodingIfFloatOutputDisabled() { - defaultAudioSink = - new DefaultAudioSink.Builder().setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES).build(); + defaultAudioSink = new DefaultAudioSink.Builder().build(); Format floatFormat = STEREO_44_1_FORMAT .buildUpon() @@ -219,11 +213,7 @@ public final class DefaultAudioSinkTest { @Config(maxSdk = 20) @Test public void floatPcmNeedsTranscodingIfFloatOutputEnabledBeforeApi21() { - defaultAudioSink = - new DefaultAudioSink.Builder() - .setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES) - .setEnableFloatOutput(true) - .build(); + defaultAudioSink = new DefaultAudioSink.Builder().setEnableFloatOutput(true).build(); Format floatFormat = STEREO_44_1_FORMAT .buildUpon() @@ -237,11 +227,7 @@ public final class DefaultAudioSinkTest { @Config(minSdk = 21) @Test public void floatOutputSupportedIfFloatOutputEnabledFromApi21() { - defaultAudioSink = - new DefaultAudioSink.Builder() - .setAudioCapabilities(DEFAULT_AUDIO_CAPABILITIES) - .setEnableFloatOutput(true) - .build(); + defaultAudioSink = new DefaultAudioSink.Builder().setEnableFloatOutput(true).build(); Format floatFormat = STEREO_44_1_FORMAT .buildUpon()