From 7edfe58283b709d5c231a7dea9c3297e74b2dd06 Mon Sep 17 00:00:00 2001 From: Cedric T Date: Mon, 18 Sep 2023 14:13:16 +0800 Subject: [PATCH] Remove current mimetype state and add DTSHD test cases --- .../exoplayer/audio/DefaultAudioSink.java | 4 - .../DefaultAudioTrackBufferSizeProvider.java | 17 ++-- ...AudioTrackBufferSizeProviderDTSHDTest.java | 78 +++++++++++++++++++ .../androidx/media3/extractor/DtsUtil.java | 13 ---- 4 files changed, 84 insertions(+), 28 deletions(-) create mode 100644 libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderDTSHDTest.java 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 b9775fa37f..19166aec9c 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 @@ -653,9 +653,6 @@ public final class DefaultAudioSink implements AudioSink { boolean enableAudioTrackPlaybackParams; boolean enableOffloadGapless = false; - if (inputFormat.sampleMimeType.contains("audio/vnd.dts")) { - DtsUtil.setCurrentMimeType(inputFormat.sampleMimeType); - } if (MimeTypes.AUDIO_RAW.equals(inputFormat.sampleMimeType)) { Assertions.checkArgument(Util.isEncodingLinearPcm(inputFormat.pcmEncoding)); @@ -1462,7 +1459,6 @@ public final class DefaultAudioSink implements AudioSink { } playing = false; offloadDisabledUntilNextConfiguration = false; - DtsUtil.clearCurrentMimeType(); } @Override diff --git a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProvider.java b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProvider.java index 951417cc0b..e3601f205e 100644 --- a/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProvider.java +++ b/libraries/exoplayer/src/main/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProvider.java @@ -69,6 +69,7 @@ public class DefaultAudioTrackBufferSizeProvider */ private static final int DTSE_BUFFER_MULTIPLICATION_FACTOR = 4; /** A builder to create {@link DefaultAudioTrackBufferSizeProvider} instances. */ + public static class Builder { private int minPcmBufferDurationUs; @@ -78,6 +79,7 @@ public class DefaultAudioTrackBufferSizeProvider private int offloadBufferDurationUs; private int ac3BufferMultiplicationFactor; private int dtseBufferMultiplicationFactor; + /** Creates a new builder. */ public Builder() { minPcmBufferDurationUs = MIN_PCM_BUFFER_DURATION_US; @@ -254,17 +256,10 @@ public class DefaultAudioTrackBufferSizeProvider int bufferSizeUs = passthroughBufferDurationUs; if (encoding == C.ENCODING_AC3) { bufferSizeUs *= ac3BufferMultiplicationFactor; - } else if ((DtsUtil.getCurrentMimeType().contentEquals(MimeTypes.AUDIO_DTS_EXPRESS) && (bitrate - != Format.NO_VALUE))) - // DTS Express for streaming uses a frame size (number of audio samples per channel per frame) - // of 4096. This requires a higher multiple for the buffersize computation. - // Need to use encoding DtsUtil.getCurrentMimeType(). ENCODING_DTS_HD cannot be used - // to represent DTS Express as some MTK firmware versions only recognises - // ENCODING_DTS for DTS Express passthrough playback. - // When bitrate is unknown (e.g. HLS-fMP4), the multiple below is not necessary as the buffer - // size is taken care of by getMaximumEncodedRateBytesPerSecond(). - { - // This is necessary to prevent buffer underflow during playback in DASH DTS Express. + } else if (encoding == C.ENCODING_DTS_HD) { + // DTS Express for streaming uses a frame size (number of audio samples per channel per frame) + // of 4096. This requires a higher multiple for the buffersize computation. Otherwise, there + // will be buffer underflow during DASH playback. bufferSizeUs *= dtseBufferMultiplicationFactor; } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderDTSHDTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderDTSHDTest.java new file mode 100644 index 0000000000..18184f1e46 --- /dev/null +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderDTSHDTest.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package androidx.media3.exoplayer.audio; + +import static androidx.media3.common.C.MICROS_PER_SECOND; +import static androidx.media3.exoplayer.audio.DefaultAudioSink.OUTPUT_MODE_PASSTHROUGH; +import static androidx.media3.exoplayer.audio.DefaultAudioTrackBufferSizeProvider.getMaximumEncodedRateBytesPerSecond; +import static com.google.common.truth.Truth.assertThat; + +import androidx.media3.common.C; +import androidx.media3.common.Format; +import androidx.test.ext.junit.runners.AndroidJUnit4; +import org.junit.Test; +import org.junit.runner.RunWith; + +/** + * Tests for {@link DefaultAudioTrackBufferSizeProvider} DTS-HD (DTS Express) audio. + */ +@RunWith(AndroidJUnit4.class) +public class DefaultAudioTrackBufferSizeProviderDTSHDTest { + + private static final DefaultAudioTrackBufferSizeProvider DEFAULT = + new DefaultAudioTrackBufferSizeProvider.Builder().build(); + + @Test + public void + getBufferSizeInBytes_passthroughDtshdAndNoBitrate_assumesMaxByteRateTimesMultiplicationFactor() { + int bufferSize = + DEFAULT.getBufferSizeInBytes( + /* minBufferSizeInBytes= */ 0, + /* encoding= */ C.ENCODING_DTS_HD, + /* outputMode= */ OUTPUT_MODE_PASSTHROUGH, + /* pcmFrameSize= */ 1, + /* sampleRate= */ 0, + /* bitrate= */ Format.NO_VALUE, + /* maxAudioTrackPlaybackSpeed= */ 1); + + assertThat(bufferSize) + .isEqualTo( + durationUsToDtshdMaxBytes(DEFAULT.passthroughBufferDurationUs) + * DEFAULT.dtseBufferMultiplicationFactor); + } + + @Test + public void + getBufferSizeInBytes_passthroughDtshdAt384Kbits_isPassthroughBufferSizeTimesMultiplicationFactor() { + int bufferSize = + DEFAULT.getBufferSizeInBytes( + /* minBufferSizeInBytes= */ 0, + /* encoding= */ C.ENCODING_DTS_HD, + /* outputMode= */ OUTPUT_MODE_PASSTHROUGH, + /* pcmFrameSize= */ 1, + /* sampleRate= */ 0, + /* bitrate= */ 384_000, + /* maxAudioTrackPlaybackSpeed= */ 1); + + // Default buffer duration 0.25s => 0.25 * 384000 / 8 = 12000 + assertThat(bufferSize).isEqualTo(12000 * DEFAULT.dtseBufferMultiplicationFactor); + } + + private static int durationUsToDtshdMaxBytes(long durationUs) { + return (int) + (durationUs * getMaximumEncodedRateBytesPerSecond(C.ENCODING_DTS_HD) / MICROS_PER_SECOND); + } +} 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 add402f02b..8e91119a59 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/DtsUtil.java @@ -76,19 +76,6 @@ public final class DtsUtil { 64, 112, 128, 192, 224, 256, 384, 448, 512, 640, 768, 896, 1024, 1152, 1280, 1536, 1920, 2048, 2304, 2560, 2688, 2816, 2823, 2944, 3072, 3840, 4096, 6144, 7680 }; - private static String currentMimeType; - - public static void setCurrentMimeType(String currentMimeType) { - DtsUtil.currentMimeType = currentMimeType; - } - - public static String getCurrentMimeType() { - return currentMimeType; - } - - public static void clearCurrentMimeType() { - currentMimeType = ""; - } /** * Returns whether a given integer matches a DTS sync word. Synchronization and storage modes are