Remove current mimetype state and add DTSHD test cases

This commit is contained in:
Cedric T 2023-09-18 14:13:16 +08:00 committed by Tianyi Feng
parent 25acaa1c81
commit 7edfe58283
4 changed files with 84 additions and 28 deletions

View File

@ -653,9 +653,6 @@ public final class DefaultAudioSink implements AudioSink {
boolean enableAudioTrackPlaybackParams; boolean enableAudioTrackPlaybackParams;
boolean enableOffloadGapless = false; boolean enableOffloadGapless = false;
if (inputFormat.sampleMimeType.contains("audio/vnd.dts")) {
DtsUtil.setCurrentMimeType(inputFormat.sampleMimeType);
}
if (MimeTypes.AUDIO_RAW.equals(inputFormat.sampleMimeType)) { if (MimeTypes.AUDIO_RAW.equals(inputFormat.sampleMimeType)) {
Assertions.checkArgument(Util.isEncodingLinearPcm(inputFormat.pcmEncoding)); Assertions.checkArgument(Util.isEncodingLinearPcm(inputFormat.pcmEncoding));
@ -1462,7 +1459,6 @@ public final class DefaultAudioSink implements AudioSink {
} }
playing = false; playing = false;
offloadDisabledUntilNextConfiguration = false; offloadDisabledUntilNextConfiguration = false;
DtsUtil.clearCurrentMimeType();
} }
@Override @Override

View File

@ -69,6 +69,7 @@ public class DefaultAudioTrackBufferSizeProvider
*/ */
private static final int DTSE_BUFFER_MULTIPLICATION_FACTOR = 4; private static final int DTSE_BUFFER_MULTIPLICATION_FACTOR = 4;
/** A builder to create {@link DefaultAudioTrackBufferSizeProvider} instances. */ /** A builder to create {@link DefaultAudioTrackBufferSizeProvider} instances. */
public static class Builder { public static class Builder {
private int minPcmBufferDurationUs; private int minPcmBufferDurationUs;
@ -78,6 +79,7 @@ public class DefaultAudioTrackBufferSizeProvider
private int offloadBufferDurationUs; private int offloadBufferDurationUs;
private int ac3BufferMultiplicationFactor; private int ac3BufferMultiplicationFactor;
private int dtseBufferMultiplicationFactor; private int dtseBufferMultiplicationFactor;
/** Creates a new builder. */ /** Creates a new builder. */
public Builder() { public Builder() {
minPcmBufferDurationUs = MIN_PCM_BUFFER_DURATION_US; minPcmBufferDurationUs = MIN_PCM_BUFFER_DURATION_US;
@ -254,17 +256,10 @@ public class DefaultAudioTrackBufferSizeProvider
int bufferSizeUs = passthroughBufferDurationUs; int bufferSizeUs = passthroughBufferDurationUs;
if (encoding == C.ENCODING_AC3) { if (encoding == C.ENCODING_AC3) {
bufferSizeUs *= ac3BufferMultiplicationFactor; bufferSizeUs *= ac3BufferMultiplicationFactor;
} else if ((DtsUtil.getCurrentMimeType().contentEquals(MimeTypes.AUDIO_DTS_EXPRESS) && (bitrate } else if (encoding == C.ENCODING_DTS_HD) {
!= Format.NO_VALUE))) // DTS Express for streaming uses a frame size (number of audio samples per channel per frame)
// 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
// of 4096. This requires a higher multiple for the buffersize computation. // will be buffer underflow during DASH playback.
// 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.
bufferSizeUs *= dtseBufferMultiplicationFactor; bufferSizeUs *= dtseBufferMultiplicationFactor;
} }

View File

@ -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);
}
}

View File

@ -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, 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 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 * Returns whether a given integer matches a DTS sync word. Synchronization and storage modes are