summaryrefslogtreecommitdiffstats
path: root/media/libstagefright/MP3Extractor.cpp
diff options
context:
space:
mode:
authorJason Simmons <jsimmons@google.com>2011-04-06 18:16:12 -0700
committerJason Simmons <jsimmons@google.com>2011-04-07 17:16:04 -0700
commita9e05b911f978dc3f25d4b1e35e51383dc4f9fc7 (patch)
tree2a7c49b003ec08c2388094e68ba73da8951db6a2 /media/libstagefright/MP3Extractor.cpp
parentcc8ace7989f663fe6c6c1ed0febca0d9d1f19c7a (diff)
downloadframeworks_av-a9e05b911f978dc3f25d4b1e35e51383dc4f9fc7.zip
frameworks_av-a9e05b911f978dc3f25d4b1e35e51383dc4f9fc7.tar.gz
frameworks_av-a9e05b911f978dc3f25d4b1e35e51383dc4f9fc7.tar.bz2
In the MP3 extractor, compute timestamps based on sample count instead of byte count.
This fixes timestamp accuracy on VBR streams. Change-Id: I73a30309536919cbeb5e5163f2f1340e2b9fa4b1
Diffstat (limited to 'media/libstagefright/MP3Extractor.cpp')
-rw-r--r--media/libstagefright/MP3Extractor.cpp38
1 files changed, 34 insertions, 4 deletions
diff --git a/media/libstagefright/MP3Extractor.cpp b/media/libstagefright/MP3Extractor.cpp
index 03ce202..4bdfc6f 100644
--- a/media/libstagefright/MP3Extractor.cpp
+++ b/media/libstagefright/MP3Extractor.cpp
@@ -48,7 +48,7 @@ static const uint32_t kMask = 0xfffe0c00;
bool MP3Extractor::get_mp3_frame_size(
uint32_t header, size_t *frame_size,
int *out_sampling_rate, int *out_channels,
- int *out_bitrate) {
+ int *out_bitrate, int *out_num_samples) {
*frame_size = 0;
if (out_sampling_rate) {
@@ -63,6 +63,10 @@ bool MP3Extractor::get_mp3_frame_size(
*out_bitrate = 0;
}
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
+
if ((header & 0xffe00000) != 0xffe00000) {
return false;
}
@@ -127,6 +131,10 @@ bool MP3Extractor::get_mp3_frame_size(
}
*frame_size = (12000 * bitrate / sampling_rate + padding) * 4;
+
+ if (out_num_samples) {
+ *out_num_samples = 384;
+ }
} else {
// layer II or III
@@ -150,10 +158,17 @@ bool MP3Extractor::get_mp3_frame_size(
bitrate = (layer == 2 /* L2 */)
? kBitrateV1L2[bitrate_index - 1]
: kBitrateV1L3[bitrate_index - 1];
+
+ if (out_num_samples) {
+ *out_num_samples = 1152;
+ }
} else {
// V2 (or 2.5)
bitrate = kBitrateV2[bitrate_index - 1];
+ if (out_num_samples) {
+ *out_num_samples = 576;
+ }
}
if (out_bitrate) {
@@ -374,6 +389,9 @@ private:
sp<MP3Seeker> mSeeker;
MediaBufferGroup *mGroup;
+ int64_t mBasisTimeUs;
+ int64_t mSamplesRead;
+
MP3Source(const MP3Source &);
MP3Source &operator=(const MP3Source &);
};
@@ -489,7 +507,9 @@ MP3Source::MP3Source(
mCurrentTimeUs(0),
mStarted(false),
mSeeker(seeker),
- mGroup(NULL) {
+ mGroup(NULL),
+ mBasisTimeUs(0),
+ mSamplesRead(0) {
}
MP3Source::~MP3Source() {
@@ -509,6 +529,9 @@ status_t MP3Source::start(MetaData *) {
mCurrentPos = mFirstFramePos;
mCurrentTimeUs = 0;
+ mBasisTimeUs = mCurrentTimeUs;
+ mSamplesRead = 0;
+
mStarted = true;
return OK;
@@ -552,6 +575,9 @@ status_t MP3Source::read(
} else {
mCurrentTimeUs = actualSeekTimeUs;
}
+
+ mBasisTimeUs = mCurrentTimeUs;
+ mSamplesRead = 0;
}
MediaBuffer *buffer;
@@ -562,6 +588,8 @@ status_t MP3Source::read(
size_t frame_size;
int bitrate;
+ int num_samples;
+ int sample_rate;
for (;;) {
ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
if (n < 4) {
@@ -575,7 +603,7 @@ status_t MP3Source::read(
if ((header & kMask) == (mFixedHeader & kMask)
&& MP3Extractor::get_mp3_frame_size(
- header, &frame_size, NULL, NULL, &bitrate)) {
+ header, &frame_size, &sample_rate, NULL, &bitrate, &num_samples)) {
break;
}
@@ -613,7 +641,9 @@ status_t MP3Source::read(
buffer->meta_data()->setInt32(kKeyIsSyncFrame, 1);
mCurrentPos += frame_size;
- mCurrentTimeUs += frame_size * 8000ll / bitrate;
+
+ mSamplesRead += num_samples;
+ mCurrentTimeUs = mBasisTimeUs + ((mSamplesRead * 1000000) / sample_rate);
*out = buffer;