am b64af9a2: Fix a number of timestamp mismatches in the mp3 extractor and decoder that would lead to invalid reporting of the current playback time for mono and/or non-44100 kHz mp3s.

Merge commit 'b64af9a221c1df4853ab7c7766d5f956c61b8765' into gingerbread-plus-aosp

* commit 'b64af9a221c1df4853ab7c7766d5f956c61b8765':
  Fix a number of timestamp mismatches in the mp3 extractor and decoder that would lead to invalid reporting of the current playback time for mono and/or non-44100 kHz mp3s.
This commit is contained in:
Andreas Huber
2010-06-23 13:00:47 -07:00
committed by Android Git Automerger
3 changed files with 39 additions and 30 deletions

View File

@@ -634,6 +634,7 @@ status_t MP3Source::read(
}
size_t frame_size;
int bitrate;
for (;;) {
ssize_t n = mDataSource->readAt(mCurrentPos, buffer->data(), 4);
if (n < 4) {
@@ -646,7 +647,7 @@ status_t MP3Source::read(
uint32_t header = U32_AT((const uint8_t *)buffer->data());
if ((header & kMask) == (mFixedHeader & kMask)
&& get_mp3_frame_size(header, &frame_size)) {
&& get_mp3_frame_size(header, &frame_size, NULL, NULL, &bitrate)) {
break;
}
@@ -683,7 +684,7 @@ status_t MP3Source::read(
buffer->meta_data()->setInt64(kKeyTime, mCurrentTimeUs);
mCurrentPos += frame_size;
mCurrentTimeUs += 1152 * 1000000 / 44100;
mCurrentTimeUs += frame_size * 8000ll / bitrate;
*out = buffer;

View File

@@ -27,13 +27,35 @@ namespace android {
MP3Decoder::MP3Decoder(const sp<MediaSource> &source)
: mSource(source),
mNumChannels(0),
mStarted(false),
mBufferGroup(NULL),
mConfig(new tPVMP3DecoderExternal),
mDecoderBuf(NULL),
mAnchorTimeUs(0),
mNumSamplesOutput(0),
mNumFramesOutput(0),
mInputBuffer(NULL) {
init();
}
void MP3Decoder::init() {
sp<MetaData> srcFormat = mSource->getFormat();
int32_t sampleRate;
CHECK(srcFormat->findInt32(kKeyChannelCount, &mNumChannels));
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
mMeta = new MetaData;
mMeta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
mMeta->setInt32(kKeyChannelCount, mNumChannels);
mMeta->setInt32(kKeySampleRate, sampleRate);
int64_t durationUs;
if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
mMeta->setInt64(kKeyDuration, durationUs);
}
mMeta->setCString(kKeyDecoderComponent, "MP3Decoder");
}
MP3Decoder::~MP3Decoder() {
@@ -62,7 +84,7 @@ status_t MP3Decoder::start(MetaData *params) {
mSource->start();
mAnchorTimeUs = 0;
mNumSamplesOutput = 0;
mNumFramesOutput = 0;
mStarted = true;
return OK;
@@ -90,26 +112,7 @@ status_t MP3Decoder::stop() {
}
sp<MetaData> MP3Decoder::getFormat() {
sp<MetaData> srcFormat = mSource->getFormat();
int32_t numChannels;
int32_t sampleRate;
CHECK(srcFormat->findInt32(kKeyChannelCount, &numChannels));
CHECK(srcFormat->findInt32(kKeySampleRate, &sampleRate));
sp<MetaData> meta = new MetaData;
meta->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
meta->setInt32(kKeyChannelCount, numChannels);
meta->setInt32(kKeySampleRate, sampleRate);
int64_t durationUs;
if (srcFormat->findInt64(kKeyDuration, &durationUs)) {
meta->setInt64(kKeyDuration, durationUs);
}
meta->setCString(kKeyDecoderComponent, "MP3Decoder");
return meta;
return mMeta;
}
status_t MP3Decoder::read(
@@ -122,7 +125,7 @@ status_t MP3Decoder::read(
if (options && options->getSeekTo(&seekTimeUs)) {
CHECK(seekTimeUs >= 0);
mNumSamplesOutput = 0;
mNumFramesOutput = 0;
if (mInputBuffer) {
mInputBuffer->release();
@@ -142,7 +145,7 @@ status_t MP3Decoder::read(
int64_t timeUs;
if (mInputBuffer->meta_data()->findInt64(kKeyTime, &timeUs)) {
mAnchorTimeUs = timeUs;
mNumSamplesOutput = 0;
mNumFramesOutput = 0;
} else {
// We must have a new timestamp after seeking.
CHECK(seekTimeUs < 0);
@@ -179,7 +182,7 @@ status_t MP3Decoder::read(
// This is recoverable, just ignore the current frame and
// play silence instead.
memset(buffer->data(), 0, mConfig->outputFrameSize);
memset(buffer->data(), 0, mConfig->outputFrameSize * sizeof(int16_t));
mConfig->inputBufferUsedLength = mInputBuffer->range_length();
}
@@ -198,9 +201,9 @@ status_t MP3Decoder::read(
buffer->meta_data()->setInt64(
kKeyTime,
mAnchorTimeUs
+ (mNumSamplesOutput * 1000000) / mConfig->samplingRate);
+ (mNumFramesOutput * 1000000) / mConfig->samplingRate);
mNumSamplesOutput += mConfig->outputFrameSize / sizeof(int16_t);
mNumFramesOutput += mConfig->outputFrameSize / mNumChannels;
*out = buffer;

View File

@@ -42,6 +42,9 @@ protected:
private:
sp<MediaSource> mSource;
sp<MetaData> mMeta;
int32_t mNumChannels;
bool mStarted;
MediaBufferGroup *mBufferGroup;
@@ -49,10 +52,12 @@ private:
tPVMP3DecoderExternal *mConfig;
void *mDecoderBuf;
int64_t mAnchorTimeUs;
int64_t mNumSamplesOutput;
int64_t mNumFramesOutput;
MediaBuffer *mInputBuffer;
void init();
MP3Decoder(const MP3Decoder &);
MP3Decoder &operator=(const MP3Decoder &);
};