Propagate format in supportsOutput
It is needed to know if gapless is needed, as gapless offload might not be supported. PiperOrigin-RevId: 315877127
This commit is contained in:
parent
285cce629f
commit
2aac0717d7
@ -142,15 +142,12 @@ public final class FfmpegAudioRenderer extends DecoderAudioRenderer {
|
||||
}
|
||||
|
||||
private boolean isOutputSupported(Format inputFormat) {
|
||||
return shouldUseFloatOutput(inputFormat)
|
||||
|| supportsOutput(inputFormat.channelCount, inputFormat.sampleRate, C.ENCODING_PCM_16BIT);
|
||||
return shouldUseFloatOutput(inputFormat) || supportsOutput(inputFormat, C.ENCODING_PCM_16BIT);
|
||||
}
|
||||
|
||||
private boolean shouldUseFloatOutput(Format inputFormat) {
|
||||
Assertions.checkNotNull(inputFormat.sampleMimeType);
|
||||
if (!enableFloatOutput
|
||||
|| !supportsOutput(
|
||||
inputFormat.channelCount, inputFormat.sampleRate, C.ENCODING_PCM_FLOAT)) {
|
||||
if (!enableFloatOutput || !supportsOutput(inputFormat, C.ENCODING_PCM_FLOAT)) {
|
||||
return false;
|
||||
}
|
||||
switch (inputFormat.sampleMimeType) {
|
||||
|
@ -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.channelCount, format.sampleRate, pcmEncoding)) {
|
||||
if (!supportsOutput(format, pcmEncoding)) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
} else if (format.drmInitData != null && format.exoMediaCryptoType == null) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
|
@ -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.channelCount, format.sampleRate, C.ENCODING_PCM_16BIT)) {
|
||||
} else if (!supportsOutput(format, C.ENCODING_PCM_16BIT)) {
|
||||
return FORMAT_UNSUPPORTED_SUBTYPE;
|
||||
} else if (!drmIsSupported) {
|
||||
return FORMAT_UNSUPPORTED_DRM;
|
||||
|
@ -18,6 +18,7 @@ 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;
|
||||
@ -187,12 +188,12 @@ public interface AudioSink {
|
||||
/**
|
||||
* Returns whether the sink supports the audio format.
|
||||
*
|
||||
* @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 format The format of the audio. {@link Format#pcmEncoding} is ignored and the {@code
|
||||
* encoding} argument is used instead.
|
||||
* @param encoding The audio encoding, or {@link Format#NO_VALUE} if not known.
|
||||
* @return Whether the sink supports the audio format.
|
||||
*/
|
||||
boolean supportsOutput(int channelCount, int sampleRate, @C.Encoding int encoding);
|
||||
boolean supportsOutput(Format format, @Encoding int encoding);
|
||||
|
||||
/**
|
||||
* Returns the playback position in the stream starting at zero, in microseconds, or
|
||||
|
@ -214,11 +214,10 @@ public abstract class DecoderAudioRenderer extends BaseRenderer implements Media
|
||||
/**
|
||||
* Returns whether the sink supports the audio format.
|
||||
*
|
||||
* @see AudioSink#supportsOutput(int, int, int)
|
||||
* @see AudioSink#supportsOutput(Format, int)
|
||||
*/
|
||||
protected final boolean supportsOutput(
|
||||
int channelCount, int sampleRateHz, @C.Encoding int encoding) {
|
||||
return audioSink.supportsOutput(channelCount, sampleRateHz, encoding);
|
||||
protected final boolean supportsOutput(Format format, @C.Encoding int encoding) {
|
||||
return audioSink.supportsOutput(format, encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -421,7 +421,7 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOutput(int channelCount, int sampleRateHz, @C.Encoding int encoding) {
|
||||
public boolean supportsOutput(Format format, @C.Encoding int encoding) {
|
||||
if (encoding == C.ENCODING_INVALID) {
|
||||
return false;
|
||||
}
|
||||
@ -433,10 +433,11 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
return encoding != C.ENCODING_PCM_FLOAT || Util.SDK_INT >= 21;
|
||||
}
|
||||
if (enableOffload
|
||||
&& isOffloadedPlaybackSupported(channelCount, sampleRateHz, encoding, audioAttributes)) {
|
||||
&& isOffloadedPlaybackSupported(
|
||||
format.channelCount, format.sampleRate, encoding, audioAttributes)) {
|
||||
return true;
|
||||
}
|
||||
return isPassthroughPlaybackSupported(encoding, channelCount);
|
||||
return isPassthroughPlaybackSupported(encoding, format.channelCount);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -475,8 +476,13 @@ public final class DefaultAudioSink implements AudioSink {
|
||||
@C.Encoding int encoding = inputEncoding;
|
||||
boolean useFloatOutput =
|
||||
enableFloatOutput
|
||||
&& supportsOutput(inputChannelCount, inputSampleRate, C.ENCODING_PCM_FLOAT)
|
||||
&& Util.isEncodingHighResolutionPcm(inputEncoding);
|
||||
&& Util.isEncodingHighResolutionPcm(inputEncoding)
|
||||
&& supportsOutput(
|
||||
new Format.Builder()
|
||||
.setChannelCount(inputChannelCount)
|
||||
.setSampleRate(inputSampleRate)
|
||||
.build(),
|
||||
C.ENCODING_PCM_FLOAT);
|
||||
AudioProcessor[] availableAudioProcessors =
|
||||
useFloatOutput ? toFloatPcmAvailableAudioProcessors : toIntPcmAvailableAudioProcessors;
|
||||
if (processingEnabled) {
|
||||
|
@ -16,7 +16,8 @@
|
||||
package com.google.android.exoplayer2.audio;
|
||||
|
||||
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;
|
||||
|
||||
@ -35,8 +36,8 @@ public class ForwardingAudioSink implements AudioSink {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean supportsOutput(int channelCount, int sampleRate, @C.Encoding int encoding) {
|
||||
return sink.supportsOutput(channelCount, sampleRate, encoding);
|
||||
public boolean supportsOutput(Format format, @Encoding int encoding) {
|
||||
return sink.supportsOutput(format, encoding);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -226,10 +226,8 @@ 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.channelCount, format.sampleRate, format.pcmEncoding))
|
||||
|| !audioSink.supportsOutput(
|
||||
format.channelCount, format.sampleRate, C.ENCODING_PCM_16BIT)) {
|
||||
&& !audioSink.supportsOutput(format, format.pcmEncoding))
|
||||
|| !audioSink.supportsOutput(format, C.ENCODING_PCM_16BIT)) {
|
||||
// Assume the decoder outputs 16-bit PCM, unless the input is raw.
|
||||
return RendererCapabilities.create(FORMAT_UNSUPPORTED_SUBTYPE);
|
||||
}
|
||||
@ -463,8 +461,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.
|
||||
if (audioSink.supportsOutput(
|
||||
/* channelCount= */ Format.NO_VALUE, format.sampleRate, C.ENCODING_E_AC3_JOC)) {
|
||||
Format eAc3JocFormat = format.buildUpon().setChannelCount(Format.NO_VALUE).build();
|
||||
if (audioSink.supportsOutput(eAc3JocFormat, 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.
|
||||
@ -472,7 +470,7 @@ public class MediaCodecAudioRenderer extends MediaCodecRenderer implements Media
|
||||
}
|
||||
|
||||
@C.Encoding int encoding = MimeTypes.getEncoding(mimeType, format.codecs);
|
||||
if (audioSink.supportsOutput(format.channelCount, format.sampleRate, encoding)) {
|
||||
if (audioSink.supportsOutput(format, encoding)) {
|
||||
return encoding;
|
||||
} else {
|
||||
return C.ENCODING_INVALID;
|
||||
|
@ -21,6 +21,7 @@ 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;
|
||||
@ -50,6 +51,11 @@ 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;
|
||||
@ -201,19 +207,13 @@ public final class DefaultAudioSinkTest {
|
||||
@Config(minSdk = OLDEST_SDK, maxSdk = 20)
|
||||
@Test
|
||||
public void doesNotSupportFloatOutputBeforeApi21() {
|
||||
assertThat(
|
||||
defaultAudioSink.supportsOutput(
|
||||
CHANNEL_COUNT_STEREO, SAMPLE_RATE_44_1, C.ENCODING_PCM_FLOAT))
|
||||
.isFalse();
|
||||
assertThat(defaultAudioSink.supportsOutput(STEREO_44_1_FORMAT, C.ENCODING_PCM_FLOAT)).isFalse();
|
||||
}
|
||||
|
||||
@Config(minSdk = 21, maxSdk = TARGET_SDK)
|
||||
@Test
|
||||
public void supportsFloatOutputFromApi21() {
|
||||
assertThat(
|
||||
defaultAudioSink.supportsOutput(
|
||||
CHANNEL_COUNT_STEREO, SAMPLE_RATE_44_1, C.ENCODING_PCM_FLOAT))
|
||||
.isTrue();
|
||||
assertThat(defaultAudioSink.supportsOutput(STEREO_44_1_FORMAT, C.ENCODING_PCM_FLOAT)).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -221,10 +221,7 @@ public final class DefaultAudioSinkTest {
|
||||
DefaultAudioSink defaultAudioSink =
|
||||
new DefaultAudioSink(
|
||||
new AudioCapabilities(new int[] {C.ENCODING_AAC_LC}, 2), new AudioProcessor[0]);
|
||||
assertThat(
|
||||
defaultAudioSink.supportsOutput(
|
||||
CHANNEL_COUNT_STEREO, SAMPLE_RATE_44_1, C.ENCODING_AAC_LC))
|
||||
.isFalse();
|
||||
assertThat(defaultAudioSink.supportsOutput(STEREO_44_1_FORMAT, C.ENCODING_AAC_LC)).isFalse();
|
||||
}
|
||||
|
||||
private void configureDefaultAudioSink(int channelCount) throws AudioSink.ConfigurationException {
|
||||
|
Loading…
x
Reference in New Issue
Block a user