From 2ad9a2e6a5a2e8f75341bc8b5cc1af68d79d3ec4 Mon Sep 17 00:00:00 2001 From: krocard Date: Wed, 8 Dec 2021 18:22:36 +0000 Subject: [PATCH] Do not allow null for DefaultAudioSink capabilities Null was equivalent to DEFAULT_AUDIO_CAPABILITIES. In favor of null safety, remove the null state. PiperOrigin-RevId: 415037404 --- RELEASENOTES.md | 2 ++ .../audio/DecoderAudioRenderer.java | 14 ++++----- .../exoplayer2/audio/DefaultAudioSink.java | 29 ++++++++++--------- .../audio/MediaCodecAudioRenderer.java | 18 ++++++++---- .../audio/DefaultAudioSinkTest.java | 22 +++----------- 5 files changed, 42 insertions(+), 43 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index c3d63ba58e..50517a1440 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -28,6 +28,8 @@ * Audio: * Add a `Builder` to `DefaultAudioSink` and deprecate the existing constructors. + * Change `AudioCapabilities` APIs to require passing explicitly + `AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES` instead of `null`. * Extractors: * Fix inconsistency with spec in H.265 SPS nal units parsing ((#9719)[https://github.com/google/ExoPlayer/issues/9719]). diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java index 5dfcbf0653..a33c7c6a3a 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DecoderAudioRenderer.java @@ -19,6 +19,7 @@ import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCA import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_REUSE_NOT_IMPLEMENTED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO; import static com.google.android.exoplayer2.source.SampleStream.FLAG_REQUIRE_FORMAT; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.Math.max; import android.os.Handler; @@ -54,7 +55,6 @@ import com.google.android.exoplayer2.util.MediaClock; import com.google.android.exoplayer2.util.MimeTypes; import com.google.android.exoplayer2.util.TraceUtil; import com.google.android.exoplayer2.util.Util; -import com.google.common.base.MoreObjects; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; @@ -163,22 +163,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/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java index 615a700fd7..f62e354daa 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/DefaultAudioSink.java @@ -15,7 +15,9 @@ */ package com.google.android.exoplayer2.audio; +import static com.google.android.exoplayer2.audio.AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.Math.max; import static java.lang.Math.min; @@ -210,7 +212,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; @@ -218,6 +220,7 @@ public final class DefaultAudioSink implements AudioSink { /** Creates a new builder. */ public Builder() { + audioCapabilities = DEFAULT_AUDIO_CAPABILITIES; offloadMode = OFFLOAD_MODE_DISABLED; } @@ -225,9 +228,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; } @@ -413,7 +417,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; @@ -486,7 +490,10 @@ public final class DefaultAudioSink implements AudioSink { imports = "com.google.android.exoplayer2.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}. */ @@ -506,7 +513,7 @@ public final class DefaultAudioSink implements AudioSink { boolean enableFloatOutput) { this( new Builder() - .setAudioCapabilities(audioCapabilities) + .setAudioCapabilities(firstNonNull(audioCapabilities, DEFAULT_AUDIO_CAPABILITIES)) .setAudioProcessors(audioProcessors) .setEnableFloatOutput(enableFloatOutput)); } @@ -532,7 +539,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) @@ -1592,7 +1599,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; } @@ -1608,11 +1615,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/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java index 76401d440a..fc9a102406 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/MediaCodecAudioRenderer.java @@ -18,6 +18,7 @@ package com.google.android.exoplayer2.audio; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.DISCARD_REASON_MAX_INPUT_SIZE_EXCEEDED; import static com.google.android.exoplayer2.decoder.DecoderReuseEvaluation.REUSE_RESULT_NO; import static com.google.android.exoplayer2.util.Assertions.checkNotNull; +import static com.google.common.base.MoreObjects.firstNonNull; import static java.lang.Math.max; import android.annotation.SuppressLint; @@ -129,7 +130,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); } /** @@ -138,8 +144,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. */ @@ -148,7 +155,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, @@ -156,7 +163,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/library/core/src/test/java/com/google/android/exoplayer2/audio/DefaultAudioSinkTest.java b/library/core/src/test/java/com/google/android/exoplayer2/audio/DefaultAudioSinkTest.java index 264cd67a68..689519ce68 100644 --- a/library/core/src/test/java/com/google/android/exoplayer2/audio/DefaultAudioSinkTest.java +++ b/library/core/src/test/java/com/google/android/exoplayer2/audio/DefaultAudioSinkTest.java @@ -15,7 +15,6 @@ */ package com.google.android.exoplayer2.audio; -import static com.google.android.exoplayer2.audio.AudioCapabilities.DEFAULT_AUDIO_CAPABILITIES; import static com.google.android.exoplayer2.audio.AudioSink.CURRENT_POSITION_NOT_SET; import static com.google.android.exoplayer2.audio.AudioSink.SINK_FORMAT_SUPPORTED_DIRECTLY; import static com.google.android.exoplayer2.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()