Loading media/libstagefright/id3/ID3.cpp +20 −9 Original line number Diff line number Diff line Loading @@ -236,11 +236,19 @@ struct id3_header { // first handle global unsynchronization bool hasGlobalUnsync = false; if (header.flags & 0x80) { ALOGV("removing unsynchronization"); ALOGV("has Global unsynchronization"); hasGlobalUnsync = true; // we have to wait on applying global unsynchronization to V2.4 frames // if we apply it now, the length information within any V2.4 frames goes bad // Removing unsynchronization shrinks the buffer, but lengths (stored in safesync // format) stored within the frame reflect "pre-shrinking" totals. // we can (and should) apply the non-2.4 synch now. if ( header.version_major != 4) { ALOGV("Apply global unsync for non V2.4 frames"); removeUnsynchronization(); } } // handle extended header, if present mFirstFrameOffset = 0; Loading Loading @@ -329,9 +337,10 @@ struct id3_header { // Handle any v2.4 per-frame unsynchronization // The id3 spec isn't clear about what should happen if the global // unsynchronization flag is combined with per-frame unsynchronization, // or whether that's even allowed, so this code assumes id3 writing // tools do the right thing and not apply double-unsynchronization, // but will honor the flags if they are set. // or whether that's even allowed. We choose a "no more than 1 unsynchronization" // semantic; the V2_4 unsynchronizer gets a copy of the global flag so it can handle // this possible ambiquity. // if (header.version_major == 4) { void *copy = malloc(size); if (copy == NULL) { Loading Loading @@ -367,7 +376,6 @@ struct id3_header { } if (header.version_major == 2) { mVersion = ID3_V2_2; } else if (header.version_major == 3) { Loading Loading @@ -445,7 +453,11 @@ bool ID3::removeUnsynchronizationV2_4(bool iTunesHack, bool hasGlobalUnsync) { flags &= ~1; } if (!hasGlobalUnsync && (flags & 2) && (dataSize >= 2)) { ALOGV("hasglobal %d flags&2 %d", hasGlobalUnsync, flags&2); if (hasGlobalUnsync && !(flags & 2)) { ALOGV("OOPS: global unsync set, but per-frame NOT set; removing unsync anyway"); } if ((hasGlobalUnsync || (flags & 2)) && (dataSize >= 2)) { // This frame has "unsynchronization", so we have to replace occurrences // of 0xff 0x00 with just 0xff in order to get the real data. Loading @@ -472,7 +484,6 @@ bool ID3::removeUnsynchronizationV2_4(bool iTunesHack, bool hasGlobalUnsync) { ALOGE("b/34618607 (%zu %zu %zu %zu)", readOffset, writeOffset, oldSize, mSize); android_errorWriteLog(0x534e4554, "34618607"); } } flags &= ~2; if (flags != prevFlags || iTunesHack) { Loading media/libstagefright/id3/test/ID3Test.cpp +32 −9 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "ID3TestEnvironment.h" using namespace android; static ID3TestEnvironment *gEnv = nullptr; Loading @@ -41,6 +42,7 @@ class ID3multiAlbumArtTest : public ::testing::TestWithParam<pair<string, int>> TEST_P(ID3tagTest, TagTest) { string path = gEnv->getRes() + GetParam(); ALOGV(" ===== TagTest for %s", path.c_str()); sp<FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; DataSourceHelper helper(file->wrap()); Loading @@ -60,6 +62,7 @@ TEST_P(ID3tagTest, TagTest) { TEST_P(ID3versionTest, VersionTest) { int versionNumber = GetParam().second; string path = gEnv->getRes() + GetParam().first; ALOGV(" ===== VersionTest for %s", path.c_str()); sp<android::FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; Loading @@ -73,6 +76,7 @@ TEST_P(ID3versionTest, VersionTest) { TEST_P(ID3textTagTest, TextTagTest) { int numTextFrames = GetParam().second; string path = gEnv->getRes() + GetParam().first; ALOGV(" ===== TextTagTest for %s", path.c_str()); sp<android::FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; Loading Loading @@ -117,6 +121,7 @@ TEST_P(ID3textTagTest, TextTagTest) { TEST_P(ID3albumArtTest, AlbumArtTest) { bool albumArtPresent = GetParam().second; string path = gEnv->getRes() + GetParam().first; ALOGV(" ===== AlbumArt for %s", path.c_str()); sp<android::FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; Loading Loading @@ -176,6 +181,17 @@ TEST_P(ID3multiAlbumArtTest, MultiAlbumArtTest) { << " album arts! \n"; } // we have a test asset with large album art -- which is larger than our 3M cap // that we inserted intentionally in the ID3 parsing routine. // Rather than have it fail all the time, we have wrapped it under an #ifdef // so that the tests will pass. #undef TEST_LARGE // it appears that bbb_2sec_v24_unsynchronizedAllFrames.mp3 is not a legal file, // so we've commented it out of the list of files to be tested // INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest, ::testing::Values("bbb_1sec_v23.mp3", "bbb_1sec_1_image.mp3", Loading @@ -187,7 +203,6 @@ INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest, "bbb_1sec_v23_3tags.mp3", "bbb_1sec_v1_5tags.mp3", "bbb_2sec_v24_unsynchronizedOneFrame.mp3", "bbb_2sec_v24_unsynchronizedAllFrames.mp3", "idv24_unsynchronized.mp3")); INSTANTIATE_TEST_SUITE_P( Loading @@ -198,12 +213,13 @@ INSTANTIATE_TEST_SUITE_P( make_pair("bbb_2sec_v24.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_1_image.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_2_image.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4), // FAIL #endif make_pair("bbb_1sec_v23_3tags.mp3", ID3::ID3_V2_3), make_pair("bbb_1sec_v1_5tags.mp3", ID3::ID3_V1_1), make_pair("bbb_1sec_v1_3tags.mp3", ID3::ID3_V1_1), make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", ID3::ID3_V2_4), make_pair("idv24_unsynchronized.mp3", ID3::ID3_V2_4))); INSTANTIATE_TEST_SUITE_P( Loading @@ -215,12 +231,14 @@ INSTANTIATE_TEST_SUITE_P( make_pair("bbb_2sec_v24.mp3", 1), make_pair("bbb_2sec_1_image.mp3", 1), make_pair("bbb_2sec_2_image.mp3", 1), make_pair("bbb_2sec_largeSize.mp3", 1), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", 1), // FAIL #endif make_pair("bbb_1sec_v23_3tags.mp3", 3), make_pair("bbb_1sec_v1_5tags.mp3", 5), make_pair("bbb_1sec_v1_3tags.mp3", 3), make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3), make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", 3))); make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3) )); INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest, ::testing::Values(make_pair("bbb_1sec_v23.mp3", false), Loading @@ -229,7 +247,9 @@ INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest, make_pair("bbb_2sec_v24.mp3", false), make_pair("bbb_2sec_1_image.mp3", true), make_pair("bbb_2sec_2_image.mp3", true), make_pair("bbb_2sec_largeSize.mp3", true), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", true), // FAIL #endif make_pair("bbb_1sec_v1_5tags.mp3", false), make_pair("idv24_unsynchronized.mp3", true) )); Loading @@ -237,11 +257,14 @@ INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest, INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3multiAlbumArtTest, ::testing::Values(make_pair("bbb_1sec_v23.mp3", 0), make_pair("bbb_2sec_v24.mp3", 0), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", 3), // FAIL #endif make_pair("bbb_1sec_1_image.mp3", 1), make_pair("bbb_2sec_1_image.mp3", 1), make_pair("bbb_1sec_2_image.mp3", 2), make_pair("bbb_2sec_2_image.mp3", 2), make_pair("bbb_2sec_largeSize.mp3", 3))); make_pair("bbb_2sec_2_image.mp3", 2) )); int main(int argc, char **argv) { gEnv = new ID3TestEnvironment(); Loading Loading
media/libstagefright/id3/ID3.cpp +20 −9 Original line number Diff line number Diff line Loading @@ -236,11 +236,19 @@ struct id3_header { // first handle global unsynchronization bool hasGlobalUnsync = false; if (header.flags & 0x80) { ALOGV("removing unsynchronization"); ALOGV("has Global unsynchronization"); hasGlobalUnsync = true; // we have to wait on applying global unsynchronization to V2.4 frames // if we apply it now, the length information within any V2.4 frames goes bad // Removing unsynchronization shrinks the buffer, but lengths (stored in safesync // format) stored within the frame reflect "pre-shrinking" totals. // we can (and should) apply the non-2.4 synch now. if ( header.version_major != 4) { ALOGV("Apply global unsync for non V2.4 frames"); removeUnsynchronization(); } } // handle extended header, if present mFirstFrameOffset = 0; Loading Loading @@ -329,9 +337,10 @@ struct id3_header { // Handle any v2.4 per-frame unsynchronization // The id3 spec isn't clear about what should happen if the global // unsynchronization flag is combined with per-frame unsynchronization, // or whether that's even allowed, so this code assumes id3 writing // tools do the right thing and not apply double-unsynchronization, // but will honor the flags if they are set. // or whether that's even allowed. We choose a "no more than 1 unsynchronization" // semantic; the V2_4 unsynchronizer gets a copy of the global flag so it can handle // this possible ambiquity. // if (header.version_major == 4) { void *copy = malloc(size); if (copy == NULL) { Loading Loading @@ -367,7 +376,6 @@ struct id3_header { } if (header.version_major == 2) { mVersion = ID3_V2_2; } else if (header.version_major == 3) { Loading Loading @@ -445,7 +453,11 @@ bool ID3::removeUnsynchronizationV2_4(bool iTunesHack, bool hasGlobalUnsync) { flags &= ~1; } if (!hasGlobalUnsync && (flags & 2) && (dataSize >= 2)) { ALOGV("hasglobal %d flags&2 %d", hasGlobalUnsync, flags&2); if (hasGlobalUnsync && !(flags & 2)) { ALOGV("OOPS: global unsync set, but per-frame NOT set; removing unsync anyway"); } if ((hasGlobalUnsync || (flags & 2)) && (dataSize >= 2)) { // This frame has "unsynchronization", so we have to replace occurrences // of 0xff 0x00 with just 0xff in order to get the real data. Loading @@ -472,7 +484,6 @@ bool ID3::removeUnsynchronizationV2_4(bool iTunesHack, bool hasGlobalUnsync) { ALOGE("b/34618607 (%zu %zu %zu %zu)", readOffset, writeOffset, oldSize, mSize); android_errorWriteLog(0x534e4554, "34618607"); } } flags &= ~2; if (flags != prevFlags || iTunesHack) { Loading
media/libstagefright/id3/test/ID3Test.cpp +32 −9 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ #include "ID3TestEnvironment.h" using namespace android; static ID3TestEnvironment *gEnv = nullptr; Loading @@ -41,6 +42,7 @@ class ID3multiAlbumArtTest : public ::testing::TestWithParam<pair<string, int>> TEST_P(ID3tagTest, TagTest) { string path = gEnv->getRes() + GetParam(); ALOGV(" ===== TagTest for %s", path.c_str()); sp<FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; DataSourceHelper helper(file->wrap()); Loading @@ -60,6 +62,7 @@ TEST_P(ID3tagTest, TagTest) { TEST_P(ID3versionTest, VersionTest) { int versionNumber = GetParam().second; string path = gEnv->getRes() + GetParam().first; ALOGV(" ===== VersionTest for %s", path.c_str()); sp<android::FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; Loading @@ -73,6 +76,7 @@ TEST_P(ID3versionTest, VersionTest) { TEST_P(ID3textTagTest, TextTagTest) { int numTextFrames = GetParam().second; string path = gEnv->getRes() + GetParam().first; ALOGV(" ===== TextTagTest for %s", path.c_str()); sp<android::FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; Loading Loading @@ -117,6 +121,7 @@ TEST_P(ID3textTagTest, TextTagTest) { TEST_P(ID3albumArtTest, AlbumArtTest) { bool albumArtPresent = GetParam().second; string path = gEnv->getRes() + GetParam().first; ALOGV(" ===== AlbumArt for %s", path.c_str()); sp<android::FileSource> file = new FileSource(path.c_str()); ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n"; Loading Loading @@ -176,6 +181,17 @@ TEST_P(ID3multiAlbumArtTest, MultiAlbumArtTest) { << " album arts! \n"; } // we have a test asset with large album art -- which is larger than our 3M cap // that we inserted intentionally in the ID3 parsing routine. // Rather than have it fail all the time, we have wrapped it under an #ifdef // so that the tests will pass. #undef TEST_LARGE // it appears that bbb_2sec_v24_unsynchronizedAllFrames.mp3 is not a legal file, // so we've commented it out of the list of files to be tested // INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest, ::testing::Values("bbb_1sec_v23.mp3", "bbb_1sec_1_image.mp3", Loading @@ -187,7 +203,6 @@ INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest, "bbb_1sec_v23_3tags.mp3", "bbb_1sec_v1_5tags.mp3", "bbb_2sec_v24_unsynchronizedOneFrame.mp3", "bbb_2sec_v24_unsynchronizedAllFrames.mp3", "idv24_unsynchronized.mp3")); INSTANTIATE_TEST_SUITE_P( Loading @@ -198,12 +213,13 @@ INSTANTIATE_TEST_SUITE_P( make_pair("bbb_2sec_v24.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_1_image.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_2_image.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4), // FAIL #endif make_pair("bbb_1sec_v23_3tags.mp3", ID3::ID3_V2_3), make_pair("bbb_1sec_v1_5tags.mp3", ID3::ID3_V1_1), make_pair("bbb_1sec_v1_3tags.mp3", ID3::ID3_V1_1), make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", ID3::ID3_V2_4), make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", ID3::ID3_V2_4), make_pair("idv24_unsynchronized.mp3", ID3::ID3_V2_4))); INSTANTIATE_TEST_SUITE_P( Loading @@ -215,12 +231,14 @@ INSTANTIATE_TEST_SUITE_P( make_pair("bbb_2sec_v24.mp3", 1), make_pair("bbb_2sec_1_image.mp3", 1), make_pair("bbb_2sec_2_image.mp3", 1), make_pair("bbb_2sec_largeSize.mp3", 1), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", 1), // FAIL #endif make_pair("bbb_1sec_v23_3tags.mp3", 3), make_pair("bbb_1sec_v1_5tags.mp3", 5), make_pair("bbb_1sec_v1_3tags.mp3", 3), make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3), make_pair("bbb_2sec_v24_unsynchronizedAllFrames.mp3", 3))); make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3) )); INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest, ::testing::Values(make_pair("bbb_1sec_v23.mp3", false), Loading @@ -229,7 +247,9 @@ INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest, make_pair("bbb_2sec_v24.mp3", false), make_pair("bbb_2sec_1_image.mp3", true), make_pair("bbb_2sec_2_image.mp3", true), make_pair("bbb_2sec_largeSize.mp3", true), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", true), // FAIL #endif make_pair("bbb_1sec_v1_5tags.mp3", false), make_pair("idv24_unsynchronized.mp3", true) )); Loading @@ -237,11 +257,14 @@ INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest, INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3multiAlbumArtTest, ::testing::Values(make_pair("bbb_1sec_v23.mp3", 0), make_pair("bbb_2sec_v24.mp3", 0), #if TEST_LARGE make_pair("bbb_2sec_largeSize.mp3", 3), // FAIL #endif make_pair("bbb_1sec_1_image.mp3", 1), make_pair("bbb_2sec_1_image.mp3", 1), make_pair("bbb_1sec_2_image.mp3", 2), make_pair("bbb_2sec_2_image.mp3", 2), make_pair("bbb_2sec_largeSize.mp3", 3))); make_pair("bbb_2sec_2_image.mp3", 2) )); int main(int argc, char **argv) { gEnv = new ID3TestEnvironment(); Loading