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
This commit is contained in:
krocard 2021-12-08 18:22:36 +00:00 committed by Oliver Woodman
parent 9676d548c3
commit 2ad9a2e6a5
5 changed files with 42 additions and 43 deletions

View File

@ -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]).

View File

@ -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());
}

View File

@ -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.
*
* <p>The default value is {@code null}.
* <p>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<Integer, Integer> 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

View File

@ -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());
}

View File

@ -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()