Support malformed ID3 V2.4 tags written by early versions of iTunes.

Change-Id: I90c2a9bbf216e2ae9a37accdaa2214233f5e54ea
related-to-bug: 3275576
diff --git a/media/libstagefright/id3/ID3.cpp b/media/libstagefright/id3/ID3.cpp
index e9131a6..45e018d 100644
--- a/media/libstagefright/id3/ID3.cpp
+++ b/media/libstagefright/id3/ID3.cpp
@@ -149,7 +149,25 @@
     }
 
     if (header.version_major == 4) {
-        if (!removeUnsynchronizationV2_4()) {
+        void *copy = malloc(size);
+        memcpy(copy, mData, size);
+
+        bool success = removeUnsynchronizationV2_4(false /* iTunesHack */);
+        if (!success) {
+            memcpy(mData, copy, size);
+            mSize = size;
+
+            success = removeUnsynchronizationV2_4(true /* iTunesHack */);
+
+            if (success) {
+                LOGV("Had to apply the iTunes hack to parse this ID3 tag");
+            }
+        }
+
+        free(copy);
+        copy = NULL;
+
+        if (!success) {
             free(mData);
             mData = NULL;
 
@@ -261,7 +279,7 @@
     }
 }
 
-bool ID3::removeUnsynchronizationV2_4() {
+bool ID3::removeUnsynchronizationV2_4(bool iTunesHack) {
     size_t oldSize = mSize;
 
     size_t offset = 0;
@@ -271,7 +289,9 @@
         }
 
         size_t dataSize;
-        if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) {
+        if (iTunesHack) {
+            dataSize = U32_AT(&mData[offset + 4]);
+        } else if (!ParseSyncsafeInteger(&mData[offset + 4], &dataSize)) {
             return false;
         }
 
@@ -308,7 +328,7 @@
             flags &= ~2;
         }
 
-        if (flags != prevFlags) {
+        if (flags != prevFlags || iTunesHack) {
             WriteSyncsafeInteger(&mData[offset + 4], dataSize);
             mData[offset + 8] = flags >> 8;
             mData[offset + 9] = flags & 0xff;
diff --git a/media/libstagefright/include/ID3.h b/media/libstagefright/include/ID3.h
index 7ddbb41..98c82a4 100644
--- a/media/libstagefright/include/ID3.h
+++ b/media/libstagefright/include/ID3.h
@@ -80,7 +80,7 @@
     bool parseV1(const sp<DataSource> &source);
     bool parseV2(const sp<DataSource> &source);
     void removeUnsynchronization();
-    bool removeUnsynchronizationV2_4();
+    bool removeUnsynchronizationV2_4(bool iTunesHack);
 
     static bool ParseSyncsafeInteger(const uint8_t encoded[4], size_t *x);