From 491b13622e79f5c2ef84771b1a29e40f47aca653 Mon Sep 17 00:00:00 2001 From: christosts Date: Tue, 15 Nov 2022 16:06:13 +0000 Subject: [PATCH] Set valid channel masks for 8 and 12 channels on all Android versions Util.getAudioTrackChannelConfig() maps a channel count to a channel mask that is passed to AudioTrack. The method expected that playback of 8-channel audio is possible from Android 5.1 and playback of 12-channel audio is only possible from Android 12L. However, there is no restriction on the upper number of channels that can be passed to the AudioTrack. google/ExoPlayer#10701 is an example where the audio decoder outputs 12 channels on an Android 10. This change removes the restrictions for 8 and 12 channels. Note, we still do not support playback of arbitrary number of channels as it would require further changes to DefaultAudioSink. #minor-release Issue: google/ExoPlayer#10701 PiperOrigin-RevId: 488659831 --- RELEASENOTES.md | 3 +++ .../androidx/media3/common/util/Util.java | 17 +++------------- .../exoplayer/audio/DefaultAudioSink.java | 20 +++++++++---------- 3 files changed, 16 insertions(+), 24 deletions(-) diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 258116b158..6fb471c892 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -58,6 +58,9 @@ Release notes output device ([#135](https://github.com/androidx/media/issues/135)). * Rename `androidx.media3.exoplayer.audio.AudioProcessor` to `androidx.media3.common.audio.AudioProcessor`. + * Map 8-channel and 12-channel audio to the 7.1 and 7.1.4 channel masks + respectively on all Android versions + ([#10701](https://github.com/google/ExoPlayer/issues/10701)). * Metadata: * `MetadataRenderer` can now be configured to render metadata as soon as they are available. Create an instance with diff --git a/libraries/common/src/main/java/androidx/media3/common/util/Util.java b/libraries/common/src/main/java/androidx/media3/common/util/Util.java index 138a2d9c9c..30d94ef39e 100644 --- a/libraries/common/src/main/java/androidx/media3/common/util/Util.java +++ b/libraries/common/src/main/java/androidx/media3/common/util/Util.java @@ -1861,6 +1861,7 @@ public static boolean isEncodingHighResolutionPcm(@C.PcmEncoding int encoding) { * @return The channel configuration or {@link AudioFormat#CHANNEL_INVALID} if output is not * possible. */ + @SuppressLint("InlinedApi") // Inlined AudioFormat constants. @UnstableApi public static int getAudioTrackChannelConfig(int channelCount) { switch (channelCount) { @@ -1879,21 +1880,9 @@ public static int getAudioTrackChannelConfig(int channelCount) { case 7: return AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER; case 8: - if (SDK_INT >= 23) { - return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; - } else if (SDK_INT >= 21) { - // Equal to AudioFormat.CHANNEL_OUT_7POINT1_SURROUND, which is hidden before Android M. - return AudioFormat.CHANNEL_OUT_5POINT1 - | AudioFormat.CHANNEL_OUT_SIDE_LEFT - | AudioFormat.CHANNEL_OUT_SIDE_RIGHT; - } else { - // 8 ch output is not supported before Android L. - return AudioFormat.CHANNEL_INVALID; - } + return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; case 12: - return Util.SDK_INT >= 32 - ? AudioFormat.CHANNEL_OUT_7POINT1POINT4 - : AudioFormat.CHANNEL_INVALID; + return AudioFormat.CHANNEL_OUT_7POINT1POINT4; default: return AudioFormat.CHANNEL_INVALID; } 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 a80d3d978c..b7657b425f 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 @@ -690,16 +690,6 @@ public void configure(Format inputFormat, int specifiedBufferSize, @Nullable int outputChannelConfig = encodingAndChannelConfig.second; } } - int bufferSize = - specifiedBufferSize != 0 - ? specifiedBufferSize - : audioTrackBufferSizeProvider.getBufferSizeInBytes( - getAudioTrackMinBufferSize(outputSampleRate, outputChannelConfig, outputEncoding), - outputEncoding, - outputMode, - outputPcmFrameSize, - outputSampleRate, - enableAudioTrackPlaybackParams ? MAX_PLAYBACK_SPEED : DEFAULT_PLAYBACK_SPEED); if (outputEncoding == C.ENCODING_INVALID) { throw new ConfigurationException( @@ -710,6 +700,16 @@ public void configure(Format inputFormat, int specifiedBufferSize, @Nullable int "Invalid output channel config (mode=" + outputMode + ") for: " + inputFormat, inputFormat); } + int bufferSize = + specifiedBufferSize != 0 + ? specifiedBufferSize + : audioTrackBufferSizeProvider.getBufferSizeInBytes( + getAudioTrackMinBufferSize(outputSampleRate, outputChannelConfig, outputEncoding), + outputEncoding, + outputMode, + outputPcmFrameSize, + outputSampleRate, + enableAudioTrackPlaybackParams ? MAX_PLAYBACK_SPEED : DEFAULT_PLAYBACK_SPEED); offloadDisabledUntilNextConfiguration = false; Configuration pendingConfiguration =