Move AC-3 bitrate calculation into Ac3Util.

This is in preparation for removing bitrate from MediaFormat.
This commit is contained in:
Oliver Woodman 2015-05-01 20:25:19 +01:00
parent 6bf62770bd
commit fafcd79e1b
3 changed files with 25 additions and 14 deletions

View file

@ -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}.

View file

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

View file

@ -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.<byte[]>emptyList());
MediaFormat.NO_VALUE, channelCount, sampleRate, Collections.<byte[]>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.<byte[]>emptyList());
Collections.<byte[]>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.
}