mirror of
https://github.com/androidx/media.git
synced 2025-04-30 06:46:50 +08:00
Use the true bitrate for CBR MP3 seeking
PiperOrigin-RevId: 225989898
This commit is contained in:
parent
ee2e89e0cd
commit
0e8e9621c0
@ -7,6 +7,7 @@
|
||||
* Support for playing spherical videos on Daydream.
|
||||
* Improve decoder re-use between playbacks. TODO: Write and link a blog post
|
||||
here ([#2826](https://github.com/google/ExoPlayer/issues/2826)).
|
||||
* Use the true bitrate for constant-bitrate MP3 seeking.
|
||||
* Track selection:
|
||||
* Add options for controlling audio track selections to `DefaultTrackSelector`
|
||||
([#3314](https://github.com/google/ExoPlayer/issues/3314)).
|
||||
|
@ -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
|
||||
@ -89,7 +99,7 @@ public final class MpegAudioHeader {
|
||||
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) {
|
||||
@ -102,10 +112,10 @@ public final class MpegAudioHeader {
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -159,7 +169,7 @@ public final class MpegAudioHeader {
|
||||
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)
|
||||
@ -167,19 +177,22 @@ public final class MpegAudioHeader {
|
||||
// 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;
|
||||
}
|
||||
|
||||
@ -198,8 +211,14 @@ public final class MpegAudioHeader {
|
||||
/** 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;
|
||||
|
@ -1,6 +1,6 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 26125
|
||||
duration = 26122
|
||||
getPosition(0) = [[timeUs=0, position=0]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
|
@ -1,6 +1,6 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 26125
|
||||
duration = 26122
|
||||
getPosition(0) = [[timeUs=0, position=0]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
|
@ -1,6 +1,6 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 26125
|
||||
duration = 26122
|
||||
getPosition(0) = [[timeUs=0, position=0]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
|
@ -1,6 +1,6 @@
|
||||
seekMap:
|
||||
isSeekable = true
|
||||
duration = 26125
|
||||
duration = 26122
|
||||
getPosition(0) = [[timeUs=0, position=0]]
|
||||
numberOfTracks = 1
|
||||
track 0:
|
||||
|
Loading…
x
Reference in New Issue
Block a user