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 e598ca6fa4..8f0d009bf9 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 @@ -63,6 +63,7 @@ import androidx.media3.extractor.AacUtil; import androidx.media3.extractor.Ac3Util; import androidx.media3.extractor.Ac4Util; import androidx.media3.extractor.DtsUtil; +import androidx.media3.extractor.ExtractorUtil; import androidx.media3.extractor.MpegAudioUtil; import androidx.media3.extractor.OpusUtil; import com.google.common.collect.ImmutableList; @@ -1479,8 +1480,7 @@ public final class DefaultAudioSink implements AudioSink { long byteRate = configuration.outputMode == OUTPUT_MODE_PCM ? (long) configuration.outputSampleRate * configuration.outputPcmFrameSize - : DefaultAudioTrackBufferSizeProvider.getMaximumEncodedRateBytesPerSecond( - configuration.outputEncoding); + : getNonPcmMaximumEncodedRateBytesPerSecond(configuration.outputEncoding); return Util.scaleLargeValue( configuration.bufferSize, C.MICROS_PER_SECOND, byteRate, RoundingMode.DOWN); } @@ -2387,6 +2387,12 @@ public final class DefaultAudioSink implements AudioSink { } } + private static int getNonPcmMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) { + int rate = ExtractorUtil.getMaximumEncodedRateBytesPerSecond(encoding); + checkState(rate != C.RATE_UNSET_INT); + return rate; + } + @RequiresApi(23) private static final class Api23 { private Api23() {} @@ -2404,8 +2410,7 @@ public final class DefaultAudioSink implements AudioSink { : Util.scaleLargeValue( audioTrack.getBufferSizeInFrames(), C.MICROS_PER_SECOND, - DefaultAudioTrackBufferSizeProvider.getMaximumEncodedRateBytesPerSecond( - configuration.outputEncoding), + getNonPcmMaximumEncodedRateBytesPerSecond(configuration.outputEncoding), RoundingMode.DOWN); } } 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 88a01d8aa8..05a8a0e8e5 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 @@ -15,6 +15,7 @@ */ package androidx.media3.exoplayer.audio; +import static androidx.media3.common.util.Assertions.checkState; import static androidx.media3.common.util.Util.constrainValue; import static androidx.media3.exoplayer.audio.DefaultAudioSink.OUTPUT_MODE_OFFLOAD; import static androidx.media3.exoplayer.audio.DefaultAudioSink.OUTPUT_MODE_PASSTHROUGH; @@ -28,12 +29,7 @@ import androidx.media3.common.C; import androidx.media3.common.Format; import androidx.media3.common.util.UnstableApi; import androidx.media3.exoplayer.audio.DefaultAudioSink.OutputMode; -import androidx.media3.extractor.AacUtil; -import androidx.media3.extractor.Ac3Util; -import androidx.media3.extractor.Ac4Util; -import androidx.media3.extractor.DtsUtil; -import androidx.media3.extractor.MpegAudioUtil; -import androidx.media3.extractor.OpusUtil; +import androidx.media3.extractor.ExtractorUtil; import com.google.errorprone.annotations.CanIgnoreReturnValue; import java.math.RoundingMode; @@ -266,13 +262,13 @@ public class DefaultAudioTrackBufferSizeProvider int byteRate = bitrate != Format.NO_VALUE ? divide(bitrate, 8, RoundingMode.CEILING) - : getMaximumEncodedRateBytesPerSecond(encoding); + : getNonPcmMaximumEncodedRateBytesPerSecond(encoding); return checkedCast((long) bufferSizeUs * byteRate / C.MICROS_PER_SECOND); } /** Returns the buffer size for offload playback. */ protected int getOffloadBufferSizeInBytes(@C.Encoding int encoding) { - int maxByteRate = getMaximumEncodedRateBytesPerSecond(encoding); + int maxByteRate = getNonPcmMaximumEncodedRateBytesPerSecond(encoding); return checkedCast((long) offloadBufferDurationUs * maxByteRate / C.MICROS_PER_SECOND); } @@ -280,49 +276,9 @@ public class DefaultAudioTrackBufferSizeProvider return checkedCast((long) durationUs * samplingRate * frameSize / C.MICROS_PER_SECOND); } - protected static int getMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) { - switch (encoding) { - case C.ENCODING_MP3: - return MpegAudioUtil.MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AAC_LC: - return AacUtil.AAC_LC_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AAC_HE_V1: - return AacUtil.AAC_HE_V1_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AAC_HE_V2: - return AacUtil.AAC_HE_V2_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AAC_XHE: - return AacUtil.AAC_XHE_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AAC_ELD: - return AacUtil.AAC_ELD_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AC3: - return Ac3Util.AC3_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_E_AC3: - case C.ENCODING_E_AC3_JOC: - return Ac3Util.E_AC3_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_AC4: - return Ac4Util.MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_DTS: - return DtsUtil.DTS_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_DTS_HD: - case C.ENCODING_DTS_UHD_P2: - return DtsUtil.DTS_HD_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_DOLBY_TRUEHD: - return Ac3Util.TRUEHD_MAX_RATE_BYTES_PER_SECOND; - case C.ENCODING_OPUS: - return OpusUtil.MAX_BYTES_PER_SECOND; - case C.ENCODING_PCM_16BIT: - case C.ENCODING_PCM_16BIT_BIG_ENDIAN: - case C.ENCODING_PCM_24BIT: - case C.ENCODING_PCM_24BIT_BIG_ENDIAN: - case C.ENCODING_PCM_32BIT: - case C.ENCODING_PCM_32BIT_BIG_ENDIAN: - case C.ENCODING_PCM_8BIT: - case C.ENCODING_PCM_FLOAT: - case C.ENCODING_AAC_ER_BSAC: - case C.ENCODING_INVALID: - case Format.NO_VALUE: - default: - throw new IllegalArgumentException(); - } + private static int getNonPcmMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) { + int rate = ExtractorUtil.getMaximumEncodedRateBytesPerSecond(encoding); + checkState(rate != C.RATE_UNSET_INT); + return rate; } } diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderAC3Test.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderAC3Test.java index fae6430f8b..3859950107 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderAC3Test.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderAC3Test.java @@ -17,7 +17,7 @@ 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 androidx.media3.extractor.ExtractorUtil.getMaximumEncodedRateBytesPerSecond; import static com.google.common.truth.Truth.assertThat; import androidx.media3.common.C; 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 index bd518167a4..12950de089 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderDTSHDTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderDTSHDTest.java @@ -17,7 +17,7 @@ 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 androidx.media3.extractor.ExtractorUtil.getMaximumEncodedRateBytesPerSecond; import static com.google.common.truth.Truth.assertThat; import androidx.media3.common.C; diff --git a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderEncodedTest.java b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderEncodedTest.java index 0d2723bb54..14d3453fc7 100644 --- a/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderEncodedTest.java +++ b/libraries/exoplayer/src/test/java/androidx/media3/exoplayer/audio/DefaultAudioTrackBufferSizeProviderEncodedTest.java @@ -17,7 +17,7 @@ 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 androidx.media3.extractor.ExtractorUtil.getMaximumEncodedRateBytesPerSecond; import static com.google.common.truth.Truth.assertThat; import androidx.media3.common.C; diff --git a/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java b/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java index a583716f39..692adbc50d 100644 --- a/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java +++ b/libraries/extractor/src/main/java/androidx/media3/extractor/ExtractorUtil.java @@ -17,6 +17,7 @@ package androidx.media3.extractor; import androidx.annotation.Nullable; import androidx.media3.common.C; +import androidx.media3.common.Format; import androidx.media3.common.ParserException; import androidx.media3.common.util.UnstableApi; import java.io.EOFException; @@ -122,5 +123,58 @@ public final class ExtractorUtil { } } + /** + * Returns the maximum encoded rate for samples of the given encoding. + * + * @param encoding A {@link C.Encoding}. + * @return The maximum encoded rate for this encoding in bytes per second, or {@link + * C#RATE_UNSET_INT} if unknown. + */ + public static int getMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) { + switch (encoding) { + case C.ENCODING_MP3: + return MpegAudioUtil.MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AAC_LC: + return AacUtil.AAC_LC_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AAC_HE_V1: + return AacUtil.AAC_HE_V1_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AAC_HE_V2: + return AacUtil.AAC_HE_V2_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AAC_XHE: + return AacUtil.AAC_XHE_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AAC_ELD: + return AacUtil.AAC_ELD_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AC3: + return Ac3Util.AC3_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_E_AC3: + case C.ENCODING_E_AC3_JOC: + return Ac3Util.E_AC3_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_AC4: + return Ac4Util.MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_DTS: + return DtsUtil.DTS_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_DTS_HD: + case C.ENCODING_DTS_UHD_P2: + return DtsUtil.DTS_HD_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_DOLBY_TRUEHD: + return Ac3Util.TRUEHD_MAX_RATE_BYTES_PER_SECOND; + case C.ENCODING_OPUS: + return OpusUtil.MAX_BYTES_PER_SECOND; + case C.ENCODING_PCM_16BIT: + case C.ENCODING_PCM_16BIT_BIG_ENDIAN: + case C.ENCODING_PCM_24BIT: + case C.ENCODING_PCM_24BIT_BIG_ENDIAN: + case C.ENCODING_PCM_32BIT: + case C.ENCODING_PCM_32BIT_BIG_ENDIAN: + case C.ENCODING_PCM_8BIT: + case C.ENCODING_PCM_FLOAT: + case C.ENCODING_AAC_ER_BSAC: + case C.ENCODING_INVALID: + case Format.NO_VALUE: + default: + return C.RATE_UNSET_INT; + } + } + private ExtractorUtil() {} }