Properly decode ADTS files with ID3 headers.

Change-Id: I55247e79ac9cc9547e3e0f6fe048bcbdc9b639d1
diff --git a/media/libstagefright/AACExtractor.cpp b/media/libstagefright/AACExtractor.cpp
index 52b1200..33f22f2 100644
--- a/media/libstagefright/AACExtractor.cpp
+++ b/media/libstagefright/AACExtractor.cpp
@@ -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 @@
     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 @@
 
     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 @@
 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 @@
 
 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 @@
     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;
     }
 
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index f54185b..2171492 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -115,7 +115,7 @@
     } 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);
     }
diff --git a/media/libstagefright/include/AACExtractor.h b/media/libstagefright/include/AACExtractor.h
index 8e5657b..e98ca82 100644
--- a/media/libstagefright/include/AACExtractor.h
+++ b/media/libstagefright/include/AACExtractor.h
@@ -29,7 +29,7 @@
 
 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);