From fc0e0d4cb8f4e89431b1d344dce16559fbc97c97 Mon Sep 17 00:00:00 2001 From: andrewlewis Date: Thu, 11 Jun 2020 19:59:50 +0100 Subject: [PATCH] Rollback of https://github.com/google/ExoPlayer/commit/2aac0717d728df5511ebac5855467e83cd2d4aa0 *** Original commit *** Propagate format in supportsOutput It is needed to know if gapless is needed, as gapless offload might not be supported. *** PiperOrigin-RevId: 315947888 --- .../ext/ffmpeg/FfmpegAudioRenderer.java | 7 +++++-- .../ext/flac/LibflacAudioRenderer.java | 2 +- .../ext/opus/LibopusAudioRenderer.java | 2 +- .../android/exoplayer2/audio/AudioSink.java | 7 +++---- .../audio/DecoderAudioRenderer.java | 7 ++++--- .../exoplayer2/audio/DefaultAudioSink.java | 16 +++++--------- .../exoplayer2/audio/ForwardingAudioSink.java | 7 +++---- .../audio/MediaCodecAudioRenderer.java | 12 ++++++----- .../audio/DefaultAudioSinkTest.java | 21 +++++++++++-------- 9 files changed, 41 insertions(+), 40 deletions(-) diff --git a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java index 7d53c519a7..f5e5281886 100644 --- a/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java +++ b/extensions/ffmpeg/src/main/java/com/google/android/exoplayer2/ext/ffmpeg/FfmpegAudioRenderer.java @@ -142,12 +142,15 @@ public final class FfmpegAudioRenderer extends DecoderAudioRenderer { } private boolean isOutputSupported(Format inputFormat) { - return shouldUseFloatOutput(inputFormat) || supportsOutput(inputFormat, C.ENCODING_PCM_16BIT); + return shouldUseFloatOutput(inputFormat) + || supportsOutput(inputFormat.channelCount, inputFormat.sampleRate, C.ENCODING_PCM_16BIT); } private boolean shouldUseFloatOutput(Format inputFormat) { Assertions.checkNotNull(inputFormat.sampleMimeType); - if (!enableFloatOutput || !supportsOutput(inputFormat, C.ENCODING_PCM_FLOAT)) { + if (!enableFloatOutput + || !supportsOutput( + inputFormat.channelCount, inputFormat.sampleRate, C.ENCODING_PCM_FLOAT)) { return false; } switch (inputFormat.sampleMimeType) { diff --git a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java index 24a247fc76..9315c302cc 100644 --- a/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java +++ b/extensions/flac/src/main/java/com/google/android/exoplayer2/ext/flac/LibflacAudioRenderer.java @@ -100,7 +100,7 @@ public final class LibflacAudioRenderer extends DecoderAudioRenderer { new FlacStreamMetadata(format.initializationData.get(0), streamMetadataOffset); pcmEncoding = Util.getPcmEncoding(streamMetadata.bitsPerSample); } - if (!supportsOutput(format, pcmEncoding)) { + if (!supportsOutput(format.channelCount, format.sampleRate, pcmEncoding)) { return FORMAT_UNSUPPORTED_SUBTYPE; } else if (format.drmInitData != null && format.exoMediaCryptoType == null) { return FORMAT_UNSUPPORTED_DRM; diff --git a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java index cafa337cf2..6fe1fa8895 100644 --- a/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java +++ b/extensions/opus/src/main/java/com/google/android/exoplayer2/ext/opus/LibopusAudioRenderer.java @@ -69,7 +69,7 @@ public class LibopusAudioRenderer extends DecoderAudioRenderer { if (!OpusLibrary.isAvailable() || !MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)) { return FORMAT_UNSUPPORTED_TYPE; - } else if (!supportsOutput(format, C.ENCODING_PCM_16BIT)) { + } else if (!supportsOutput(format.channelCount, format.sampleRate, C.ENCODING_PCM_16BIT)) { return FORMAT_UNSUPPORTED_SUBTYPE; } else if (!drmIsSupported) { return FORMAT_UNSUPPORTED_DRM; diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java index 8d1fa0cc4f..8bebd97a67 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/AudioSink.java @@ -18,7 +18,6 @@ package com.google.android.exoplayer2.audio; import android.media.AudioTrack; import androidx.annotation.Nullable; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.C.Encoding; import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.PlaybackParameters; import java.nio.ByteBuffer; @@ -188,12 +187,12 @@ public interface AudioSink { /** * Returns whether the sink supports the audio format. * - * @param format The format of the audio. {@link Format#pcmEncoding} is ignored and the {@code - * encoding} argument is used instead. + * @param channelCount The number of channels, or {@link Format#NO_VALUE} if not known. + * @param sampleRate The sample rate, or {@link Format#NO_VALUE} if not known. * @param encoding The audio encoding, or {@link Format#NO_VALUE} if not known. * @return Whether the sink supports the audio format. */ - boolean supportsOutput(Format format, @Encoding int encoding); + boolean supportsOutput(int channelCount, int sampleRate, @C.Encoding int encoding); /** * Returns the playback position in the stream starting at zero, in microseconds, or 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 72a49caa29..9f1fe07c39 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 @@ -214,10 +214,11 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media /** * Returns whether the sink supports the audio format. * - * @see AudioSink#supportsOutput(Format, int) + * @see AudioSink#supportsOutput(int, int, int) */ - protected final boolean supportsOutput(Format format, @C.Encoding int encoding) { - return audioSink.supportsOutput(format, encoding); + protected final boolean supportsOutput( + int channelCount, int sampleRateHz, @C.Encoding int encoding) { + return audioSink.supportsOutput(channelCount, sampleRateHz, encoding); } @Override 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 425d786380..880aefdbbd 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 @@ -421,7 +421,7 @@ public final class DefaultAudioSink implements AudioSink { } @Override - public boolean supportsOutput(Format format, @C.Encoding int encoding) { + public boolean supportsOutput(int channelCount, int sampleRateHz, @C.Encoding int encoding) { if (encoding == C.ENCODING_INVALID) { return false; } @@ -433,11 +433,10 @@ public final class DefaultAudioSink implements AudioSink { return encoding != C.ENCODING_PCM_FLOAT || Util.SDK_INT >= 21; } if (enableOffload - && isOffloadedPlaybackSupported( - format.channelCount, format.sampleRate, encoding, audioAttributes)) { + && isOffloadedPlaybackSupported(channelCount, sampleRateHz, encoding, audioAttributes)) { return true; } - return isPassthroughPlaybackSupported(encoding, format.channelCount); + return isPassthroughPlaybackSupported(encoding, channelCount); } @Override @@ -476,13 +475,8 @@ public final class DefaultAudioSink implements AudioSink { @C.Encoding int encoding = inputEncoding; boolean useFloatOutput = enableFloatOutput - && Util.isEncodingHighResolutionPcm(inputEncoding) - && supportsOutput( - new Format.Builder() - .setChannelCount(inputChannelCount) - .setSampleRate(inputSampleRate) - .build(), - C.ENCODING_PCM_FLOAT); + && supportsOutput(inputChannelCount, inputSampleRate, C.ENCODING_PCM_FLOAT) + && Util.isEncodingHighResolutionPcm(inputEncoding); AudioProcessor[] availableAudioProcessors = useFloatOutput ? toFloatPcmAvailableAudioProcessors : toIntPcmAvailableAudioProcessors; if (processingEnabled) { diff --git a/library/core/src/main/java/com/google/android/exoplayer2/audio/ForwardingAudioSink.java b/library/core/src/main/java/com/google/android/exoplayer2/audio/ForwardingAudioSink.java index f01b55a3f1..e0703f2aa3 100644 --- a/library/core/src/main/java/com/google/android/exoplayer2/audio/ForwardingAudioSink.java +++ b/library/core/src/main/java/com/google/android/exoplayer2/audio/ForwardingAudioSink.java @@ -16,8 +16,7 @@ package com.google.android.exoplayer2.audio; import androidx.annotation.Nullable; -import com.google.android.exoplayer2.C.Encoding; -import com.google.android.exoplayer2.Format; +import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.PlaybackParameters; import java.nio.ByteBuffer; @@ -36,8 +35,8 @@ public class ForwardingAudioSink implements AudioSink { } @Override - public boolean supportsOutput(Format format, @Encoding int encoding) { - return sink.supportsOutput(format, encoding); + public boolean supportsOutput(int channelCount, int sampleRate, @C.Encoding int encoding) { + return sink.supportsOutput(channelCount, sampleRate, encoding); } @Override 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 f953d38866..2e6dc79afb 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 @@ -226,8 +226,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport); } if ((MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) - && !audioSink.supportsOutput(format, format.pcmEncoding)) - || !audioSink.supportsOutput(format, C.ENCODING_PCM_16BIT)) { + && !audioSink.supportsOutput( + format.channelCount, format.sampleRate, format.pcmEncoding)) + || !audioSink.supportsOutput( + format.channelCount, format.sampleRate, C.ENCODING_PCM_16BIT)) { // Assume the decoder outputs 16-bit PCM, unless the input is raw. return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE); } @@ -461,8 +463,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media } if (MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)) { // E-AC3 JOC is object-based so the output channel count is arbitrary. - Format eAc3JocFormat = format.buildUpon().setChannelCount(Format.NO_VALUE).build(); - if (audioSink.supportsOutput(eAc3JocFormat, C.ENCODING_E_AC3_JOC)) { + if (audioSink.supportsOutput( + /* channelCount= */ Format.NO_VALUE, format.sampleRate, C.ENCODING_E_AC3_JOC)) { return MimeTypes.getEncoding(MimeTypes.AUDIO_E_AC3_JOC, format.codecs); } // E-AC3 receivers can decode JOC streams, but in 2-D rather than 3-D, so try to fall back. @@ -470,7 +472,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media } @C.Encoding int encoding = MimeTypes.getEncoding(mimeType, format.codecs); - if (audioSink.supportsOutput(format, encoding)) { + if (audioSink.supportsOutput(format.channelCount, format.sampleRate, encoding)) { return encoding; } else { return C.ENCODING_INVALID; 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 7102bcd5ea..e916ca549f 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 @@ -21,7 +21,6 @@ import static org.robolectric.annotation.Config.TARGET_SDK; import androidx.test.ext.junit.runners.AndroidJUnit4; import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.Format; import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.Arrays; @@ -51,11 +50,6 @@ public final class DefaultAudioSinkTest { private static final int SAMPLE_RATE_44_1 = 44100; private static final int TRIM_100_MS_FRAME_COUNT = 4410; private static final int TRIM_10_MS_FRAME_COUNT = 441; - private static final Format STEREO_44_1_FORMAT = - new Format.Builder() - .setChannelCount(CHANNEL_COUNT_STEREO) - .setSampleRate(SAMPLE_RATE_44_1) - .build(); private DefaultAudioSink defaultAudioSink; private ArrayAudioBufferSink arrayAudioBufferSink; @@ -207,13 +201,19 @@ public final class DefaultAudioSinkTest { @Config(minSdk = OLDEST_SDK, maxSdk = 20) @Test public void doesNotSupportFloatOutputBeforeApi21() { - assertThat(defaultAudioSink.supportsOutput(STEREO_44_1_FORMAT, C.ENCODING_PCM_FLOAT)).isFalse(); + assertThat( + defaultAudioSink.supportsOutput( + CHANNEL_COUNT_STEREO, SAMPLE_RATE_44_1, C.ENCODING_PCM_FLOAT)) + .isFalse(); } @Config(minSdk = 21, maxSdk = TARGET_SDK) @Test public void supportsFloatOutputFromApi21() { - assertThat(defaultAudioSink.supportsOutput(STEREO_44_1_FORMAT, C.ENCODING_PCM_FLOAT)).isTrue(); + assertThat( + defaultAudioSink.supportsOutput( + CHANNEL_COUNT_STEREO, SAMPLE_RATE_44_1, C.ENCODING_PCM_FLOAT)) + .isTrue(); } @Test @@ -221,7 +221,10 @@ public final class DefaultAudioSinkTest { DefaultAudioSink defaultAudioSink = new DefaultAudioSink( new AudioCapabilities(new int[] {C.ENCODING_AAC_LC}, 2), new AudioProcessor[0]); - assertThat(defaultAudioSink.supportsOutput(STEREO_44_1_FORMAT, C.ENCODING_AAC_LC)).isFalse(); + assertThat( + defaultAudioSink.supportsOutput( + CHANNEL_COUNT_STEREO, SAMPLE_RATE_44_1, C.ENCODING_AAC_LC)) + .isFalse(); } private void configureDefaultAudioSink(int channelCount) throws AudioSink.ConfigurationException {