Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix DTS Express Audio Buffer Underflow Issue. #650

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Rename DTSE to DTSHD
  • Loading branch information
cedricxperi authored and tianyif committed Oct 12, 2023
commit 24d03b06254380384a643c609ccc4bbaed976e25
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
import android.media.AudioTrack;
import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.audio.DefaultAudioSink.OutputMode;
import androidx.media3.extractor.AacUtil;
Expand Down Expand Up @@ -67,8 +66,11 @@ public class DefaultAudioTrackBufferSizeProvider
* Default multiplication factor to apply to DTS Express passthrough buffer to avoid underruns
* on some devices (e.g., Xiaomi A2 TV).
*/
private static final int DTSE_BUFFER_MULTIPLICATION_FACTOR = 4;
/** A builder to create {@link DefaultAudioTrackBufferSizeProvider} instances. */
private static final int DTSHD_BUFFER_MULTIPLICATION_FACTOR = 4;

/**
* A builder to create {@link DefaultAudioTrackBufferSizeProvider} instances.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Since there is no actual required diff at lines 71-74, could you please revert these lines back to the original state?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

*/

public static class Builder {

Expand All @@ -78,7 +80,7 @@ public static class Builder {
private int passthroughBufferDurationUs;
private int offloadBufferDurationUs;
private int ac3BufferMultiplicationFactor;
private int dtseBufferMultiplicationFactor;
private int dtshdBufferMultiplicationFactor;

/** Creates a new builder. */
public Builder() {
Expand All @@ -88,7 +90,7 @@ public Builder() {
passthroughBufferDurationUs = PASSTHROUGH_BUFFER_DURATION_US;
offloadBufferDurationUs = OFFLOAD_BUFFER_DURATION_US;
ac3BufferMultiplicationFactor = AC3_BUFFER_MULTIPLICATION_FACTOR;
dtseBufferMultiplicationFactor = DTSE_BUFFER_MULTIPLICATION_FACTOR;
dtshdBufferMultiplicationFactor = DTSHD_BUFFER_MULTIPLICATION_FACTOR;
}

/**
Expand Down Expand Up @@ -152,13 +154,13 @@ public Builder setAc3BufferMultiplicationFactor(int ac3BufferMultiplicationFacto
}

/**
* Sets the multiplication factor to apply to the passthrough buffer for DTS Express to avoid
* underruns on some devices (e.g., Xiaomi A2 TV). Default is
* {@value #DTSE_BUFFER_MULTIPLICATION_FACTOR}.
* Sets the multiplication factor to apply to the passthrough buffer for DTS-HD (DTS Express)
* to avoid underruns on some devices (e.g., Xiaomi A2 TV). Default is
* {@value #DTSHD_BUFFER_MULTIPLICATION_FACTOR}.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: {@link #DTSHD_BUFFER_MULTIPLICATION_FACTOR} instead of @value.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

*/
@CanIgnoreReturnValue
public Builder setDtseBufferMultiplicationFactor(int dtseBufferMultiplicationFactor) {
this.dtseBufferMultiplicationFactor = dtseBufferMultiplicationFactor;
public Builder setDtshdBufferMultiplicationFactor(int dtshdBufferMultiplicationFactor) {
this.dtshdBufferMultiplicationFactor = dtshdBufferMultiplicationFactor;
return this;
}

Expand Down Expand Up @@ -189,18 +191,18 @@ public DefaultAudioTrackBufferSizeProvider build() {
*/
public final int ac3BufferMultiplicationFactor;
/**
* The multiplication factor to apply to DTS Express passthrough buffer to avoid underruns on some
* devices (e.g., Xiaomi A2 TV).
* The multiplication factor to apply to DTS-HD (DTS Express) passthrough buffer to avoid
* underruns on some devices (e.g., Xiaomi A2 TV).
*/
public final int dtseBufferMultiplicationFactor;
public final int dtshdBufferMultiplicationFactor;
protected DefaultAudioTrackBufferSizeProvider(Builder builder) {
minPcmBufferDurationUs = builder.minPcmBufferDurationUs;
maxPcmBufferDurationUs = builder.maxPcmBufferDurationUs;
pcmBufferMultiplicationFactor = builder.pcmBufferMultiplicationFactor;
passthroughBufferDurationUs = builder.passthroughBufferDurationUs;
offloadBufferDurationUs = builder.offloadBufferDurationUs;
ac3BufferMultiplicationFactor = builder.ac3BufferMultiplicationFactor;
dtseBufferMultiplicationFactor = builder.dtseBufferMultiplicationFactor;
dtshdBufferMultiplicationFactor = builder.dtshdBufferMultiplicationFactor;
}

@Override
Expand Down Expand Up @@ -257,10 +259,10 @@ protected int getPassthroughBufferSizeInBytes(@C.Encoding int encoding, int bitr
if (encoding == C.ENCODING_AC3) {
bufferSizeUs *= ac3BufferMultiplicationFactor;
} 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;
// DTSHD (DTS Express) for streaming uses a frame size (number of audio samples per channel
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

super-nit: DTS-HD (a dash "-" in between)?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// per frame of 4096. This requires a higher multiple for the buffersize computation.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: A missing closing ) after the second word "frame"? The corresponding open ( is in the last line.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

// Otherwise, there will be buffer underflow during DASH playback.
bufferSizeUs *= dtshdBufferMultiplicationFactor;
}

int byteRate =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ public class DefaultAudioTrackBufferSizeProviderDTSHDTest {
assertThat(bufferSize)
.isEqualTo(
durationUsToDtshdMaxBytes(DEFAULT.passthroughBufferDurationUs)
* DEFAULT.dtseBufferMultiplicationFactor);
* DEFAULT.dtshdBufferMultiplicationFactor);
}

@Test
Expand All @@ -68,7 +68,7 @@ public class DefaultAudioTrackBufferSizeProviderDTSHDTest {
/* maxAudioTrackPlaybackSpeed= */ 1);

// Default buffer duration 0.25s => 0.25 * 384000 / 8 = 12000
assertThat(bufferSize).isEqualTo(12000 * DEFAULT.dtseBufferMultiplicationFactor);
assertThat(bufferSize).isEqualTo(12000 * DEFAULT.dtshdBufferMultiplicationFactor);
}

private static int durationUsToDtshdMaxBytes(long durationUs) {
Expand Down