Commit fc0e0d4c by andrewlewis Committed by Oliver Woodman

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
parent 8afc0c34
...@@ -142,12 +142,15 @@ public final class FfmpegAudioRenderer extends DecoderAudioRenderer { ...@@ -142,12 +142,15 @@ public final class FfmpegAudioRenderer extends DecoderAudioRenderer {
} }
private boolean isOutputSupported(Format inputFormat) { 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) { private boolean shouldUseFloatOutput(Format inputFormat) {
Assertions.checkNotNull(inputFormat.sampleMimeType); 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; return false;
} }
switch (inputFormat.sampleMimeType) { switch (inputFormat.sampleMimeType) {
......
...@@ -100,7 +100,7 @@ public final class LibflacAudioRenderer extends DecoderAudioRenderer { ...@@ -100,7 +100,7 @@ public final class LibflacAudioRenderer extends DecoderAudioRenderer {
new FlacStreamMetadata(format.initializationData.get(0), streamMetadataOffset); new FlacStreamMetadata(format.initializationData.get(0), streamMetadataOffset);
pcmEncoding = Util.getPcmEncoding(streamMetadata.bitsPerSample); pcmEncoding = Util.getPcmEncoding(streamMetadata.bitsPerSample);
} }
if (!supportsOutput(format, pcmEncoding)) { if (!supportsOutput(format.channelCount, format.sampleRate, pcmEncoding)) {
return FORMAT_UNSUPPORTED_SUBTYPE; return FORMAT_UNSUPPORTED_SUBTYPE;
} else if (format.drmInitData != null && format.exoMediaCryptoType == null) { } else if (format.drmInitData != null && format.exoMediaCryptoType == null) {
return FORMAT_UNSUPPORTED_DRM; return FORMAT_UNSUPPORTED_DRM;
......
...@@ -69,7 +69,7 @@ public class LibopusAudioRenderer extends DecoderAudioRenderer { ...@@ -69,7 +69,7 @@ public class LibopusAudioRenderer extends DecoderAudioRenderer {
if (!OpusLibrary.isAvailable() if (!OpusLibrary.isAvailable()
|| !MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)) { || !MimeTypes.AUDIO_OPUS.equalsIgnoreCase(format.sampleMimeType)) {
return FORMAT_UNSUPPORTED_TYPE; 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; return FORMAT_UNSUPPORTED_SUBTYPE;
} else if (!drmIsSupported) { } else if (!drmIsSupported) {
return FORMAT_UNSUPPORTED_DRM; return FORMAT_UNSUPPORTED_DRM;
......
...@@ -18,7 +18,6 @@ package com.google.android.exoplayer2.audio; ...@@ -18,7 +18,6 @@ package com.google.android.exoplayer2.audio;
import android.media.AudioTrack; import android.media.AudioTrack;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.C.Encoding;
import com.google.android.exoplayer2.Format; import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -188,12 +187,12 @@ public interface AudioSink { ...@@ -188,12 +187,12 @@ public interface AudioSink {
/** /**
* Returns whether the sink supports the audio format. * Returns whether the sink supports the audio format.
* *
* @param format The format of the audio. {@link Format#pcmEncoding} is ignored and the {@code * @param channelCount The number of channels, or {@link Format#NO_VALUE} if not known.
* encoding} argument is used instead. * @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. * @param encoding The audio encoding, or {@link Format#NO_VALUE} if not known.
* @return Whether the sink supports the audio format. * @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 * Returns the playback position in the stream starting at zero, in microseconds, or
......
...@@ -214,10 +214,11 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media ...@@ -214,10 +214,11 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media
/** /**
* Returns whether the sink supports the audio format. * 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) { protected final boolean supportsOutput(
return audioSink.supportsOutput(format, encoding); int channelCount, int sampleRateHz, @C.Encoding int encoding) {
return audioSink.supportsOutput(channelCount, sampleRateHz, encoding);
} }
@Override @Override
......
...@@ -421,7 +421,7 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -421,7 +421,7 @@ public final class DefaultAudioSink implements AudioSink {
} }
@Override @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) { if (encoding == C.ENCODING_INVALID) {
return false; return false;
} }
...@@ -433,11 +433,10 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -433,11 +433,10 @@ public final class DefaultAudioSink implements AudioSink {
return encoding != C.ENCODING_PCM_FLOAT || Util.SDK_INT >= 21; return encoding != C.ENCODING_PCM_FLOAT || Util.SDK_INT >= 21;
} }
if (enableOffload if (enableOffload
&& isOffloadedPlaybackSupported( && isOffloadedPlaybackSupported(channelCount, sampleRateHz, encoding, audioAttributes)) {
format.channelCount, format.sampleRate, encoding, audioAttributes)) {
return true; return true;
} }
return isPassthroughPlaybackSupported(encoding, format.channelCount); return isPassthroughPlaybackSupported(encoding, channelCount);
} }
@Override @Override
...@@ -476,13 +475,8 @@ public final class DefaultAudioSink implements AudioSink { ...@@ -476,13 +475,8 @@ public final class DefaultAudioSink implements AudioSink {
@C.Encoding int encoding = inputEncoding; @C.Encoding int encoding = inputEncoding;
boolean useFloatOutput = boolean useFloatOutput =
enableFloatOutput enableFloatOutput
&& Util.isEncodingHighResolutionPcm(inputEncoding) && supportsOutput(inputChannelCount, inputSampleRate, C.ENCODING_PCM_FLOAT)
&& supportsOutput( && Util.isEncodingHighResolutionPcm(inputEncoding);
new Format.Builder()
.setChannelCount(inputChannelCount)
.setSampleRate(inputSampleRate)
.build(),
C.ENCODING_PCM_FLOAT);
AudioProcessor[] availableAudioProcessors = AudioProcessor[] availableAudioProcessors =
useFloatOutput ? toFloatPcmAvailableAudioProcessors : toIntPcmAvailableAudioProcessors; useFloatOutput ? toFloatPcmAvailableAudioProcessors : toIntPcmAvailableAudioProcessors;
if (processingEnabled) { if (processingEnabled) {
......
...@@ -16,8 +16,7 @@ ...@@ -16,8 +16,7 @@
package com.google.android.exoplayer2.audio; package com.google.android.exoplayer2.audio;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import com.google.android.exoplayer2.C.Encoding; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import com.google.android.exoplayer2.PlaybackParameters; import com.google.android.exoplayer2.PlaybackParameters;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
...@@ -36,8 +35,8 @@ public class ForwardingAudioSink implements AudioSink { ...@@ -36,8 +35,8 @@ public class ForwardingAudioSink implements AudioSink {
} }
@Override @Override
public boolean supportsOutput(Format format, @Encoding int encoding) { public boolean supportsOutput(int channelCount, int sampleRate, @C.Encoding int encoding) {
return sink.supportsOutput(format, encoding); return sink.supportsOutput(channelCount, sampleRate, encoding);
} }
@Override @Override
......
...@@ -226,8 +226,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -226,8 +226,10 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport); return RendererCapabilities.create(FORMAT_HANDLED, ADAPTIVE_NOT_SEAMLESS, tunnelingSupport);
} }
if ((MimeTypes.AUDIO_RAW.equals(format.sampleMimeType) if ((MimeTypes.AUDIO_RAW.equals(format.sampleMimeType)
&& !audioSink.supportsOutput(format, format.pcmEncoding)) && !audioSink.supportsOutput(
|| !audioSink.supportsOutput(format, C.ENCODING_PCM_16BIT)) { 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. // Assume the decoder outputs 16-bit PCM, unless the input is raw.
return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE); return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE);
} }
...@@ -461,8 +463,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media ...@@ -461,8 +463,8 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
} }
if (MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)) { if (MimeTypes.AUDIO_E_AC3_JOC.equals(mimeType)) {
// E-AC3 JOC is object-based so the output channel count is arbitrary. // 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(
if (audioSink.supportsOutput(eAc3JocFormat, C.ENCODING_E_AC3_JOC)) { /* channelCount= */ Format.NO_VALUE, format.sampleRate, C.ENCODING_E_AC3_JOC)) {
return MimeTypes.getEncoding(MimeTypes.AUDIO_E_AC3_JOC, format.codecs); 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. // 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 ...@@ -470,7 +472,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
} }
@C.Encoding int encoding = MimeTypes.getEncoding(mimeType, format.codecs); @C.Encoding int encoding = MimeTypes.getEncoding(mimeType, format.codecs);
if (audioSink.supportsOutput(format, encoding)) { if (audioSink.supportsOutput(format.channelCount, format.sampleRate, encoding)) {
return encoding; return encoding;
} else { } else {
return C.ENCODING_INVALID; return C.ENCODING_INVALID;
......
...@@ -21,7 +21,6 @@ import static org.robolectric.annotation.Config.TARGET_SDK; ...@@ -21,7 +21,6 @@ import static org.robolectric.annotation.Config.TARGET_SDK;
import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.android.exoplayer2.C; import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.Format;
import java.nio.ByteBuffer; import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.Arrays; import java.util.Arrays;
...@@ -51,11 +50,6 @@ public final class DefaultAudioSinkTest { ...@@ -51,11 +50,6 @@ public final class DefaultAudioSinkTest {
private static final int SAMPLE_RATE_44_1 = 44100; private static final int SAMPLE_RATE_44_1 = 44100;
private static final int TRIM_100_MS_FRAME_COUNT = 4410; private static final int TRIM_100_MS_FRAME_COUNT = 4410;
private static final int TRIM_10_MS_FRAME_COUNT = 441; 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 DefaultAudioSink defaultAudioSink;
private ArrayAudioBufferSink arrayAudioBufferSink; private ArrayAudioBufferSink arrayAudioBufferSink;
...@@ -207,13 +201,19 @@ public final class DefaultAudioSinkTest { ...@@ -207,13 +201,19 @@ public final class DefaultAudioSinkTest {
@Config(minSdk = OLDEST_SDK, maxSdk = 20) @Config(minSdk = OLDEST_SDK, maxSdk = 20)
@Test @Test
public void doesNotSupportFloatOutputBeforeApi21() { 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) @Config(minSdk = 21, maxSdk = TARGET_SDK)
@Test @Test
public void supportsFloatOutputFromApi21() { 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 @Test
...@@ -221,7 +221,10 @@ public final class DefaultAudioSinkTest { ...@@ -221,7 +221,10 @@ public final class DefaultAudioSinkTest {
DefaultAudioSink defaultAudioSink = DefaultAudioSink defaultAudioSink =
new DefaultAudioSink( new DefaultAudioSink(
new AudioCapabilities(new int[] {C.ENCODING_AAC_LC}, 2), new AudioProcessor[0]); 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 { private void configureDefaultAudioSink(int channelCount) throws AudioSink.ConfigurationException {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment