Properly decode ADTS files with ID3 headers.

Change-Id: I55247e79ac9cc9547e3e0f6fe048bcbdc9b639d1
This commit is contained in:
Andreas Huber
2011-11-01 11:01:01 -07:00
parent 688ff9a7d6
commit fe5f0aae65
3 changed files with 60 additions and 12 deletions

View File

@@ -22,6 +22,7 @@
#include "include/avc_utils.h"
#include <media/stagefright/foundation/ABuffer.h>
#include <media/stagefright/foundation/AMessage.h>
#include <media/stagefright/DataSource.h>
#include <media/stagefright/MediaBufferGroup.h>
#include <media/stagefright/MediaDebug.h>
@@ -131,18 +132,28 @@ static size_t getAdtsFrameLength(const sp<DataSource> &source, off64_t offset, s
return frameSize;
}
AACExtractor::AACExtractor(const sp<DataSource> &source)
AACExtractor::AACExtractor(
const sp<DataSource> &source, const sp<AMessage> &_meta)
: mDataSource(source),
mInitCheck(NO_INIT),
mFrameDurationUs(0) {
String8 mimeType;
float confidence;
if (!SniffAAC(mDataSource, &mimeType, &confidence, NULL)) {
return;
sp<AMessage> meta = _meta;
if (meta == NULL) {
String8 mimeType;
float confidence;
sp<AMessage> _meta;
if (!SniffAAC(mDataSource, &mimeType, &confidence, &meta)) {
return;
}
}
int64_t offset;
CHECK(meta->findInt64("offset", &offset));
uint8_t profile, sf_index, channel, header[2];
if (mDataSource->readAt(2, &header, 2) < 2) {
if (mDataSource->readAt(offset + 2, &header, 2) < 2) {
return;
}
@@ -156,7 +167,6 @@ AACExtractor::AACExtractor(const sp<DataSource> &source)
mMeta = MakeAACCodecSpecificData(profile, sf_index, channel);
off64_t offset = 0;
off64_t streamSize, numFrames = 0;
size_t frameSize = 0;
int64_t duration = 0;
@@ -245,7 +255,12 @@ AACSource::~AACSource() {
status_t AACSource::start(MetaData *params) {
CHECK(!mStarted);
mOffset = 0;
if (mOffsetVector.empty()) {
mOffset = 0;
} else {
mOffset = mOffsetVector.itemAt(0);
}
mCurrentTimeUs = 0;
mGroup = new MediaBufferGroup;
mGroup->add_buffer(new MediaBuffer(kMaxFrameSize));
@@ -318,10 +333,39 @@ status_t AACSource::read(
bool SniffAAC(
const sp<DataSource> &source, String8 *mimeType, float *confidence,
sp<AMessage> *) {
sp<AMessage> *meta) {
off64_t pos = 0;
for (;;) {
uint8_t id3header[10];
if (source->readAt(pos, id3header, sizeof(id3header))
< (ssize_t)sizeof(id3header)) {
return false;
}
if (memcmp("ID3", id3header, 3)) {
break;
}
// Skip the ID3v2 header.
size_t len =
((id3header[6] & 0x7f) << 21)
| ((id3header[7] & 0x7f) << 14)
| ((id3header[8] & 0x7f) << 7)
| (id3header[9] & 0x7f);
len += 10;
pos += len;
ALOGV("skipped ID3 tag, new starting offset is %lld (0x%016llx)",
pos, pos);
}
uint8_t header[2];
if (source->readAt(0, &header, 2) != 2) {
if (source->readAt(pos, &header, 2) != 2) {
return false;
}
@@ -329,6 +373,10 @@ bool SniffAAC(
if ((header[0] == 0xff) && ((header[1] & 0xf6) == 0xf0)) {
*mimeType = MEDIA_MIMETYPE_AUDIO_AAC_ADTS;
*confidence = 0.2;
*meta = new AMessage;
(*meta)->setInt64("offset", pos);
return true;
}

View File

@@ -115,7 +115,7 @@ sp<MediaExtractor> MediaExtractor::Create(
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_WVM)) {
ret = new WVMExtractor(source);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC_ADTS)) {
ret = new AACExtractor(source);
ret = new AACExtractor(source, meta);
} else if (!strcasecmp(mime, MEDIA_MIMETYPE_CONTAINER_MPEG2PS)) {
ret = new MPEG2PSExtractor(source);
}

View File

@@ -29,7 +29,7 @@ class String8;
class AACExtractor : public MediaExtractor {
public:
AACExtractor(const sp<DataSource> &source);
AACExtractor(const sp<DataSource> &source, const sp<AMessage> &meta);
virtual size_t countTracks();
virtual sp<MediaSource> getTrack(size_t index);