Skip to content

Commit

Permalink
Use the true bitrate for CBR MP3 seeking
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 225989898
  • Loading branch information
andrewlewis authored and ojw28 committed Dec 19, 2018
1 parent 78cdd5f commit 975ed6c
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 24 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,26 @@ public final class MpegAudioHeader {
private static final String[] MIME_TYPE_BY_LAYER =
new String[] {MimeTypes.AUDIO_MPEG_L1, MimeTypes.AUDIO_MPEG_L2, MimeTypes.AUDIO_MPEG};
private static final int[] SAMPLING_RATE_V1 = {44100, 48000, 32000};
private static final int[] BITRATE_V1_L1 =
{32, 64, 96, 128, 160, 192, 224, 256, 288, 320, 352, 384, 416, 448};
private static final int[] BITRATE_V2_L1 =
{32, 48, 56, 64, 80, 96, 112, 128, 144, 160, 176, 192, 224, 256};
private static final int[] BITRATE_V1_L2 =
{32, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320, 384};
private static final int[] BITRATE_V1_L3 =
{32, 40, 48, 56, 64, 80, 96, 112, 128, 160, 192, 224, 256, 320};
private static final int[] BITRATE_V2 =
{8, 16, 24, 32, 40, 48, 56, 64, 80, 96, 112, 128, 144, 160};
private static final int[] BITRATE_V1_L1 = {
32000, 64000, 96000, 128000, 160000, 192000, 224000, 256000, 288000, 320000, 352000, 384000,
416000, 448000
};
private static final int[] BITRATE_V2_L1 = {
32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 176000, 192000,
224000, 256000
};
private static final int[] BITRATE_V1_L2 = {
32000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000,
320000, 384000
};
private static final int[] BITRATE_V1_L3 = {
32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 160000, 192000, 224000, 256000,
320000
};
private static final int[] BITRATE_V2 = {
8000, 16000, 24000, 32000, 40000, 48000, 56000, 64000, 80000, 96000, 112000, 128000, 144000,
160000
};

/**
* Returns the size of the frame associated with {@code header}, or {@link C#LENGTH_UNSET} if it
Expand Down Expand Up @@ -89,7 +99,7 @@ public static int getFrameSize(int header) {
if (layer == 3) {
// Layer I (layer == 3)
bitrate = version == 3 ? BITRATE_V1_L1[bitrateIndex - 1] : BITRATE_V2_L1[bitrateIndex - 1];
return (12000 * bitrate / samplingRate + padding) * 4;
return (12 * bitrate / samplingRate + padding) * 4;
} else {
// Layer II (layer == 2) or III (layer == 1)
if (version == 3) {
Expand All @@ -102,10 +112,10 @@ public static int getFrameSize(int header) {

if (version == 3) {
// Version 1
return 144000 * bitrate / samplingRate + padding;
return 144 * bitrate / samplingRate + padding;
} else {
// Version 2 or 2.5
return (layer == 1 ? 72000 : 144000) * bitrate / samplingRate + padding;
return (layer == 1 ? 72 : 144) * bitrate / samplingRate + padding;
}
}

Expand Down Expand Up @@ -159,27 +169,30 @@ public static boolean populateHeader(int headerData, MpegAudioHeader header) {
if (layer == 3) {
// Layer I (layer == 3)
bitrate = version == 3 ? BITRATE_V1_L1[bitrateIndex - 1] : BITRATE_V2_L1[bitrateIndex - 1];
frameSize = (12000 * bitrate / sampleRate + padding) * 4;
frameSize = (12 * bitrate / sampleRate + padding) * 4;
samplesPerFrame = 384;
} else {
// Layer II (layer == 2) or III (layer == 1)
if (version == 3) {
// Version 1
bitrate = layer == 2 ? BITRATE_V1_L2[bitrateIndex - 1] : BITRATE_V1_L3[bitrateIndex - 1];
samplesPerFrame = 1152;
frameSize = 144000 * bitrate / sampleRate + padding;
frameSize = 144 * bitrate / sampleRate + padding;
} else {
// Version 2 or 2.5.
bitrate = BITRATE_V2[bitrateIndex - 1];
samplesPerFrame = layer == 1 ? 576 : 1152;
frameSize = (layer == 1 ? 72000 : 144000) * bitrate / sampleRate + padding;
frameSize = (layer == 1 ? 72 : 144) * bitrate / sampleRate + padding;
}
}

// Calculate the bitrate in the same way Mp3Extractor calculates sample timestamps so that
// seeking to a given timestamp and playing from the start up to that timestamp give the same
// results for CBR streams. See also [internal: b/120390268].
bitrate = 8 * frameSize * sampleRate / samplesPerFrame;
String mimeType = MIME_TYPE_BY_LAYER[3 - layer];
int channels = ((headerData >> 6) & 3) == 3 ? 1 : 2;
header.setValues(version, mimeType, frameSize, sampleRate, channels, bitrate * 1000,
samplesPerFrame);
header.setValues(version, mimeType, frameSize, sampleRate, channels, bitrate, samplesPerFrame);
return true;
}

Expand All @@ -198,8 +211,14 @@ public static boolean populateHeader(int headerData, MpegAudioHeader header) {
/** Number of samples stored in the frame. */
public int samplesPerFrame;

private void setValues(int version, String mimeType, int frameSize, int sampleRate, int channels,
int bitrate, int samplesPerFrame) {
private void setValues(
int version,
String mimeType,
int frameSize,
int sampleRate,
int channels,
int bitrate,
int samplesPerFrame) {
this.version = version;
this.mimeType = mimeType;
this.frameSize = frameSize;
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/test/assets/mp3/play-trimmed.mp3.0.dump
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
seekMap:
isSeekable = true
duration = 26125
duration = 26122
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/test/assets/mp3/play-trimmed.mp3.1.dump
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
seekMap:
isSeekable = true
duration = 26125
duration = 26122
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/test/assets/mp3/play-trimmed.mp3.2.dump
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
seekMap:
isSeekable = true
duration = 26125
duration = 26122
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
Expand Down
2 changes: 1 addition & 1 deletion library/core/src/test/assets/mp3/play-trimmed.mp3.3.dump
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
seekMap:
isSeekable = true
duration = 26125
duration = 26122
getPosition(0) = [[timeUs=0, position=0]]
numberOfTracks = 1
track 0:
Expand Down

0 comments on commit 975ed6c

Please sign in to comment.