diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java index cedf500c07..030a5da250 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioSink.java @@ -686,7 +686,7 @@ public boolean supportsFormat(Format format) { // For PCM formats, convert the format to what our audio processors will produce. boolean transcodingViaAudioProcessors = false; if (Util.isEncodingLinearPcm(format.pcmEncoding)) { - boolean usesFloatPcm = shouldUseFloatOutput(format.pcmEncoding); + boolean usesFloatPcm = shouldUseFloatOutput(format); if (usesFloatPcm && format.pcmEncoding != C.ENCODING_PCM_FLOAT) { format = format.buildUpon().setPcmEncoding(C.ENCODING_PCM_FLOAT).build(); transcodingViaAudioProcessors = true; @@ -750,7 +750,7 @@ public void configure(AudioSinkConfig audioSinkConfig) throws ConfigurationExcep ImmutableList.Builder pipelineProcessors = new ImmutableList.Builder<>(); pipelineProcessors.addAll(availableAudioProcessors); - if (shouldUseFloatOutput(inputFormat.pcmEncoding)) { + if (shouldUseFloatOutput(inputFormat)) { pipelineProcessors.add(toFloatPcmAudioProcessor); } else { pipelineProcessors.add(toInt16PcmAudioProcessor); @@ -1667,9 +1667,7 @@ private boolean shouldApplyAudioProcessorPlaybackParameters() { // - when playing encoded audio via passthrough/offload, because modifying the audio stream // would require decoding/re-encoding; and // - when outputting float PCM audio, because SonicAudioProcessor outputs 16-bit integer PCM. - return !tunneling - && configuration.isPcm() - && !shouldUseFloatOutput(configuration.inputFormat.pcmEncoding); + return !tunneling && configuration.isPcm() && !shouldUseFloatOutput(configuration.inputFormat); } private boolean useAudioOutputPlaybackParams() { @@ -1677,11 +1675,25 @@ private boolean useAudioOutputPlaybackParams() { } /** - * Returns whether audio in the specified PCM encoding should be written to the audio output as + * Returns whether audio in the specified PCM format should be written to the audio output as * float PCM. */ - private boolean shouldUseFloatOutput(@C.PcmEncoding int pcmEncoding) { - return enableFloatOutput && Util.isEncodingHighResolutionPcm(pcmEncoding); + private boolean shouldUseFloatOutput(Format format) { + boolean supportsFloat = + audioOutputProvider.getFormatSupport( + getFormatConfig( + format.buildUpon().setPcmEncoding(C.ENCODING_PCM_FLOAT).build())) + .supportLevel + != AudioOutputProvider.FORMAT_UNSUPPORTED; + boolean preferFloat = Util.isEncodingHighResolutionPcm(format.pcmEncoding); + // If the AudioOutputProvider cannot output 16-bit PCM, we should use float output. + boolean supportsInt16 = + audioOutputProvider.getFormatSupport( + getFormatConfig( + format.buildUpon().setPcmEncoding(C.ENCODING_PCM_16BIT).build())) + .supportLevel + != AudioOutputProvider.FORMAT_UNSUPPORTED; + return supportsFloat && enableFloatOutput && (preferFloat || !supportsInt16); } /**