From fafcd79e1b8bed1c4323049d6e2ea9af029fed70 Mon Sep 17 00:00:00 2001 From: Oliver Woodman Date: Fri, 1 May 2015 20:25:19 +0100 Subject: [PATCH] Move AC-3 bitrate calculation into Ac3Util. This is in preparation for removing bitrate from MediaFormat. --- .../android/exoplayer/audio/AudioTrack.java | 7 ++---- .../exoplayer/extractor/ts/Ac3Reader.java | 8 ++++--- .../android/exoplayer/util/Ac3Util.java | 24 ++++++++++++++----- 3 files changed, 25 insertions(+), 14 deletions(-) diff --git a/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java b/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java index fb0adb6ab8..cc6ca7b263 100644 --- a/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java +++ b/library/src/main/java/com/google/android/exoplayer/audio/AudioTrack.java @@ -16,6 +16,7 @@ package com.google.android.exoplayer.audio; import com.google.android.exoplayer.C; +import com.google.android.exoplayer.util.Ac3Util; import com.google.android.exoplayer.util.Assertions; import com.google.android.exoplayer.util.Util; @@ -433,11 +434,7 @@ public final class AudioTrack { int result = 0; if (temporaryBufferSize == 0) { if (isAc3 && ac3Bitrate == UNKNOWN_AC3_BITRATE) { - // Each AC-3 buffer contains 1536 frames of audio, so the AudioTrack playback position - // advances by 1536 per buffer (32 ms at 48 kHz). Calculate the bitrate in kbit/s. - int unscaledAc3Bitrate = size * 8 * sampleRate; - int divisor = 1000 * 1536; - ac3Bitrate = (unscaledAc3Bitrate + divisor / 2) / divisor; + ac3Bitrate = Ac3Util.getBitrate(size, sampleRate); } // This is the first time we've seen this {@code buffer}. diff --git a/library/src/main/java/com/google/android/exoplayer/extractor/ts/Ac3Reader.java b/library/src/main/java/com/google/android/exoplayer/extractor/ts/Ac3Reader.java index 9a57acbc72..c11453c572 100644 --- a/library/src/main/java/com/google/android/exoplayer/extractor/ts/Ac3Reader.java +++ b/library/src/main/java/com/google/android/exoplayer/extractor/ts/Ac3Reader.java @@ -46,6 +46,7 @@ import com.google.android.exoplayer.util.ParsableByteArray; private long frameDurationUs; private MediaFormat mediaFormat; private int sampleSize; + private int bitrate; // Used when reading the samples. private long timeUs; @@ -149,14 +150,15 @@ import com.google.android.exoplayer.util.ParsableByteArray; * Parses the sample header. */ private void parseHeader() { + headerScratchBits.setPosition(0); + sampleSize = Ac3Util.parseFrameSize(headerScratchBits); if (mediaFormat == null) { headerScratchBits.setPosition(0); mediaFormat = Ac3Util.parseFrameAc3Format(headerScratchBits); output.format(mediaFormat); + bitrate = Ac3Util.getBitrate(sampleSize, mediaFormat.sampleRate); } - headerScratchBits.setPosition(0); - sampleSize = Ac3Util.parseFrameSize(headerScratchBits); - frameDurationUs = (int) (1000000L * 8 * sampleSize / mediaFormat.bitrate); + frameDurationUs = (int) (1000L * 8 * sampleSize / bitrate); } } diff --git a/library/src/main/java/com/google/android/exoplayer/util/Ac3Util.java b/library/src/main/java/com/google/android/exoplayer/util/Ac3Util.java index 91059832f2..e96db51361 100644 --- a/library/src/main/java/com/google/android/exoplayer/util/Ac3Util.java +++ b/library/src/main/java/com/google/android/exoplayer/util/Ac3Util.java @@ -50,10 +50,8 @@ public final class Ac3Util { if ((nextByte & 0x04) != 0) { channelCount++; } - // Map bit_rate_code onto a bitrate in bit/s. - int bitrate = BITRATES[((nextByte & 0x03) << 3) + (data.readUnsignedByte() >> 5)] * 1000; return MediaFormat.createAudioFormat(MimeTypes.AUDIO_AC3, MediaFormat.NO_VALUE, - MediaFormat.NO_VALUE, channelCount, sampleRate, bitrate, Collections.emptyList()); + MediaFormat.NO_VALUE, channelCount, sampleRate, Collections.emptyList()); } /** @@ -91,8 +89,7 @@ public final class Ac3Util { data.skipBits(4 * 8); int fscod = data.readBits(2); - int frmsizecod = data.readBits(6); - data.skipBits(8); // bsid (5 bits) + bsmod (3 bits) + data.skipBits(14); // frmsizecod(6) + bsid (5 bits) + bsmod (3 bits) int acmod = data.readBits(3); if ((acmod & 0x01) != 0 && acmod != 1) { data.skipBits(2); // cmixlev @@ -106,7 +103,7 @@ public final class Ac3Util { boolean lfeon = data.readBit(); return MediaFormat.createAudioFormat(MimeTypes.AUDIO_AC3, MediaFormat.NO_VALUE, MediaFormat.NO_VALUE, CHANNEL_COUNTS[acmod] + (lfeon ? 1 : 0), SAMPLE_RATES[fscod], - BITRATES[frmsizecod / 2] * 1000, Collections.emptyList()); + Collections.emptyList()); } /** @@ -133,6 +130,21 @@ public final class Ac3Util { } } + /** + * Returns the bitrate of AC-3 audio given the size of a buffer and the sample rate. + * + * @param bufferSize Size in bytes of a full buffer of samples. + * @param sampleRate Sample rate in hz. + * @return Bitrate of the audio stream in kbit/s. + */ + public static int getBitrate(int bufferSize, int sampleRate) { + // Each AC-3 buffer contains 1536 frames of audio, so the AudioTrack playback position + // advances by 1536 per buffer (32 ms at 48 kHz). + int unscaledBitrate = bufferSize * 8 * sampleRate; + int divisor = 1000 * 1536; + return (unscaledBitrate + divisor / 2) / divisor; + } + private Ac3Util() { // Prevent instantiation. }