From b73d2cc736486cbb9bcf0c7abc008f878a5e1216 Mon Sep 17 00:00:00 2001 From: Cedric T Date: Tue, 18 Apr 2023 20:53:45 +0800 Subject: [PATCH] Add direct passthrough support for DTS audio. --- .../java/androidx/media3/common/MimeTypes.java | 4 ++++ .../java/androidx/media3/common/util/Util.java | 8 ++++++++ .../exoplayer/audio/AudioCapabilities.java | 13 ++++++++++--- .../java/androidx/media3/extractor/DtsUtil.java | 16 ++++++++++++++++ 4 files changed, 38 insertions(+), 3 deletions(-) diff --git a/libraries/common/src/main/java/androidx/media3/common/MimeTypes.java b/libraries/common/src/main/java/androidx/media3/common/MimeTypes.java index 5c9742e79d..27db8c9305 100644 --- a/libraries/common/src/main/java/androidx/media3/common/MimeTypes.java +++ b/libraries/common/src/main/java/androidx/media3/common/MimeTypes.java @@ -595,6 +595,10 @@ public final class MimeTypes { return C.ENCODING_DTS; case MimeTypes.AUDIO_DTS_HD: return C.ENCODING_DTS_HD; + case MimeTypes.AUDIO_DTS_EXPRESS: + return C.ENCODING_DTS; // This should be ENCODING_DTS_HD when IC platforms support it. + case MimeTypes.AUDIO_DTS_X: + return C.ENCODING_DTS; // This should be ENCODING_DTS_UHD_P2 when IC platforms support it. case MimeTypes.AUDIO_TRUEHD: return C.ENCODING_DOLBY_TRUEHD; case MimeTypes.AUDIO_OPUS: 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 377b8bf6d8..ac87584747 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 @@ -1884,6 +1884,14 @@ public final class Util { return AudioFormat.CHANNEL_OUT_5POINT1 | AudioFormat.CHANNEL_OUT_BACK_CENTER; case 8: return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; + case 10: + if (Util.SDK_INT > 31) { + return AudioFormat.CHANNEL_OUT_5POINT1POINT4; + } else { + // This is used by DTS:X P2 with Direct Passthrough Playback. + // Specifying the audio format as 7.1 for 10 channels does not affect the playback. + return AudioFormat.CHANNEL_OUT_7POINT1_SURROUND; + } case 12: return AudioFormat.CHANNEL_OUT_7POINT1POINT4; default: diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java index 499a2ae51c..57dc24e650 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/AudioCapabilities.java @@ -59,8 +59,9 @@ public final class AudioCapabilities { @SuppressWarnings("InlinedApi") private static final AudioCapabilities EXTERNAL_SURROUND_SOUND_CAPABILITIES = new AudioCapabilities( - new int[] { - AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_AC3, AudioFormat.ENCODING_E_AC3 + new int[]{ + AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_AC3, AudioFormat.ENCODING_E_AC3, + AudioFormat.ENCODING_DTS, AudioFormat.ENCODING_DTS_HD }, DEFAULT_MAX_CHANNEL_COUNT); @@ -220,7 +221,13 @@ public final class AudioCapabilities { channelCount = getMaxSupportedChannelCountForPassthrough(encoding, sampleRate); } else { channelCount = format.channelCount; - if (channelCount > maxChannelCount) { + if (format.sampleMimeType == MimeTypes.AUDIO_DTS_X) { + if (channelCount > 10) { + // To fix wrong reporting from device. ChannelCount is reported as 8 for DTS:X P2 + // on some devices. + return null; + } + } else if (channelCount > maxChannelCount) { return null; } } diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java index 75e4004125..b835b231af 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java @@ -41,6 +41,9 @@ public final class DtsUtil { private static final int SYNC_VALUE_14B_BE = 0x1FFFE800; private static final int SYNC_VALUE_LE = 0xFE7F0180; private static final int SYNC_VALUE_14B_LE = 0xFF1F00E8; + private static final int SYNC_EXT_SUB_LE = 0x25205864; + private static final int SYNC_FTOC_LE = 0xF21B4140; + private static final int SYNC_FTOC_NON_SYNC_LE = 0xE842C471; private static final byte FIRST_BYTE_BE = (byte) (SYNC_VALUE_BE >>> 24); private static final byte FIRST_BYTE_14B_BE = (byte) (SYNC_VALUE_14B_BE >>> 24); private static final byte FIRST_BYTE_LE = (byte) (SYNC_VALUE_LE >>> 24); @@ -149,6 +152,19 @@ public final class DtsUtil { * @return The number of audio samples represented by the syncframe. */ public static int parseDtsAudioSampleCount(ByteBuffer buffer) { + + // Check for sync or non sync word for DTS:X Profile 2. + // DTS:X Profile 2's FrameSize = 1024. + if ((buffer.getInt(0) == SYNC_FTOC_LE) || + (buffer.getInt(0) == SYNC_FTOC_NON_SYNC_LE)) { + return 1024; + } + // Check for sync word for DTS Express. + // DTS Express's FrameSize = 4096. + else if (buffer.getInt(0) == SYNC_EXT_SUB_LE) { + return 4096; + } + // See ETSI TS 102 114 subsection 5.4.1. int position = buffer.position(); int nblks;