Move getMaximumEncodedRateBytesPerSecond to a shared public util

This makes it more easily reusable.

Issue: androidx/media#2339
PiperOrigin-RevId: 748713531
This commit is contained in:
tonihei 2025-04-17 09:50:29 -07:00 committed by Copybara-Service
parent 52db3a240d
commit c4c3e5e0c8
6 changed files with 74 additions and 59 deletions

View File

@ -63,6 +63,7 @@ import androidx.media3.extractor.AacUtil;
import androidx.media3.extractor.Ac3Util; import androidx.media3.extractor.Ac3Util;
import androidx.media3.extractor.Ac4Util; import androidx.media3.extractor.Ac4Util;
import androidx.media3.extractor.DtsUtil; import androidx.media3.extractor.DtsUtil;
import androidx.media3.extractor.ExtractorUtil;
import androidx.media3.extractor.MpegAudioUtil; import androidx.media3.extractor.MpegAudioUtil;
import androidx.media3.extractor.OpusUtil; import androidx.media3.extractor.OpusUtil;
import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList;
@ -1479,8 +1480,7 @@ public final class DefaultAudioSink implements AudioSink {
long byteRate = long byteRate =
configuration.outputMode == OUTPUT_MODE_PCM configuration.outputMode == OUTPUT_MODE_PCM
? (long) configuration.outputSampleRate * configuration.outputPcmFrameSize ? (long) configuration.outputSampleRate * configuration.outputPcmFrameSize
: DefaultAudioTrackBufferSizeProvider.getMaximumEncodedRateBytesPerSecond( : getNonPcmMaximumEncodedRateBytesPerSecond(configuration.outputEncoding);
configuration.outputEncoding);
return Util.scaleLargeValue( return Util.scaleLargeValue(
configuration.bufferSize, C.MICROS_PER_SECOND, byteRate, RoundingMode.DOWN); 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) @RequiresApi(23)
private static final class Api23 { private static final class Api23 {
private Api23() {} private Api23() {}
@ -2404,8 +2410,7 @@ public final class DefaultAudioSink implements AudioSink {
: Util.scaleLargeValue( : Util.scaleLargeValue(
audioTrack.getBufferSizeInFrames(), audioTrack.getBufferSizeInFrames(),
C.MICROS_PER_SECOND, C.MICROS_PER_SECOND,
DefaultAudioTrackBufferSizeProvider.getMaximumEncodedRateBytesPerSecond( getNonPcmMaximumEncodedRateBytesPerSecond(configuration.outputEncoding),
configuration.outputEncoding),
RoundingMode.DOWN); RoundingMode.DOWN);
} }
} }

View File

@ -15,6 +15,7 @@
*/ */
package androidx.media3.exoplayer.audio; 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.common.util.Util.constrainValue;
import static androidx.media3.exoplayer.audio.DefaultAudioSink.OUTPUT_MODE_OFFLOAD; import static androidx.media3.exoplayer.audio.DefaultAudioSink.OUTPUT_MODE_OFFLOAD;
import static androidx.media3.exoplayer.audio.DefaultAudioSink.OUTPUT_MODE_PASSTHROUGH; 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.Format;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import androidx.media3.exoplayer.audio.DefaultAudioSink.OutputMode; import androidx.media3.exoplayer.audio.DefaultAudioSink.OutputMode;
import androidx.media3.extractor.AacUtil; import androidx.media3.extractor.ExtractorUtil;
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 com.google.errorprone.annotations.CanIgnoreReturnValue; import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.math.RoundingMode; import java.math.RoundingMode;
@ -266,13 +262,13 @@ public class DefaultAudioTrackBufferSizeProvider
int byteRate = int byteRate =
bitrate != Format.NO_VALUE bitrate != Format.NO_VALUE
? divide(bitrate, 8, RoundingMode.CEILING) ? divide(bitrate, 8, RoundingMode.CEILING)
: getMaximumEncodedRateBytesPerSecond(encoding); : getNonPcmMaximumEncodedRateBytesPerSecond(encoding);
return checkedCast((long) bufferSizeUs * byteRate / C.MICROS_PER_SECOND); return checkedCast((long) bufferSizeUs * byteRate / C.MICROS_PER_SECOND);
} }
/** Returns the buffer size for offload playback. */ /** Returns the buffer size for offload playback. */
protected int getOffloadBufferSizeInBytes(@C.Encoding int encoding) { protected int getOffloadBufferSizeInBytes(@C.Encoding int encoding) {
int maxByteRate = getMaximumEncodedRateBytesPerSecond(encoding); int maxByteRate = getNonPcmMaximumEncodedRateBytesPerSecond(encoding);
return checkedCast((long) offloadBufferDurationUs * maxByteRate / C.MICROS_PER_SECOND); 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); return checkedCast((long) durationUs * samplingRate * frameSize / C.MICROS_PER_SECOND);
} }
protected static int getMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) { private static int getNonPcmMaximumEncodedRateBytesPerSecond(@C.Encoding int encoding) {
switch (encoding) { int rate = ExtractorUtil.getMaximumEncodedRateBytesPerSecond(encoding);
case C.ENCODING_MP3: checkState(rate != C.RATE_UNSET_INT);
return MpegAudioUtil.MAX_RATE_BYTES_PER_SECOND; return rate;
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();
}
} }
} }

View File

@ -17,7 +17,7 @@ package androidx.media3.exoplayer.audio;
import static androidx.media3.common.C.MICROS_PER_SECOND; 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.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 static com.google.common.truth.Truth.assertThat;
import androidx.media3.common.C; import androidx.media3.common.C;

View File

@ -17,7 +17,7 @@ package androidx.media3.exoplayer.audio;
import static androidx.media3.common.C.MICROS_PER_SECOND; 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.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 static com.google.common.truth.Truth.assertThat;
import androidx.media3.common.C; import androidx.media3.common.C;

View File

@ -17,7 +17,7 @@ package androidx.media3.exoplayer.audio;
import static androidx.media3.common.C.MICROS_PER_SECOND; 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.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 static com.google.common.truth.Truth.assertThat;
import androidx.media3.common.C; import androidx.media3.common.C;

View File

@ -17,6 +17,7 @@ package androidx.media3.extractor;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import androidx.media3.common.C; import androidx.media3.common.C;
import androidx.media3.common.Format;
import androidx.media3.common.ParserException; import androidx.media3.common.ParserException;
import androidx.media3.common.util.UnstableApi; import androidx.media3.common.util.UnstableApi;
import java.io.EOFException; 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() {} private ExtractorUtil() {}
} }