blob: 9da28d2b063f2252d1de239e96d0b44f3c7ccedb [file] [log] [blame]
Neelkamal Semwal8776dd42019-11-26 10:21:10 +05301/*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//#define LOG_NDEBUG 0
18#define LOG_TAG "ID3Test"
19#include <utils/Log.h>
20
21#include <ctype.h>
22#include <string>
23#include <sys/stat.h>
24#include <datasource/FileSource.h>
25
26#include <media/stagefright/foundation/hexdump.h>
Harish Mahendrakard1056c22020-05-01 12:28:33 -070027#include <media/MediaExtractorPluginHelper.h>
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053028#include <ID3.h>
29
30#include "ID3TestEnvironment.h"
31
Ray Essick6626fd22021-04-28 19:08:44 -070032
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053033using namespace android;
34
35static ID3TestEnvironment *gEnv = nullptr;
36
37class ID3tagTest : public ::testing::TestWithParam<string> {};
38class ID3versionTest : public ::testing::TestWithParam<pair<string, int>> {};
39class ID3textTagTest : public ::testing::TestWithParam<pair<string, int>> {};
40class ID3albumArtTest : public ::testing::TestWithParam<pair<string, bool>> {};
41class ID3multiAlbumArtTest : public ::testing::TestWithParam<pair<string, int>> {};
42
43TEST_P(ID3tagTest, TagTest) {
44 string path = gEnv->getRes() + GetParam();
Ray Essick6626fd22021-04-28 19:08:44 -070045 ALOGV(" ===== TagTest for %s", path.c_str());
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053046 sp<FileSource> file = new FileSource(path.c_str());
47 ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
Harish Mahendrakard1056c22020-05-01 12:28:33 -070048 DataSourceHelper helper(file->wrap());
49 ID3 tag(&helper);
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053050 ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
51
52 ID3::Iterator it(tag, nullptr);
53 while (!it.done()) {
54 String8 id;
55 it.getID(&id);
Neelkamal Semwale821a502020-04-08 14:28:53 +053056 ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053057 ALOGV("Found ID tag: %s\n", String8(id).c_str());
58 it.next();
59 }
60}
61
62TEST_P(ID3versionTest, VersionTest) {
63 int versionNumber = GetParam().second;
64 string path = gEnv->getRes() + GetParam().first;
Ray Essick6626fd22021-04-28 19:08:44 -070065 ALOGV(" ===== VersionTest for %s", path.c_str());
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053066 sp<android::FileSource> file = new FileSource(path.c_str());
67 ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
68
Harish Mahendrakard1056c22020-05-01 12:28:33 -070069 DataSourceHelper helper(file->wrap());
70 ID3 tag(&helper);
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053071 ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
Neelkamal Semwale821a502020-04-08 14:28:53 +053072 ASSERT_EQ(tag.version(), versionNumber)
Ray Essick0c89ab22020-04-25 13:00:09 -070073 << "Found version: " << tag.version() << " Expected version: " << versionNumber;
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053074}
75
76TEST_P(ID3textTagTest, TextTagTest) {
77 int numTextFrames = GetParam().second;
78 string path = gEnv->getRes() + GetParam().first;
Ray Essick6626fd22021-04-28 19:08:44 -070079 ALOGV(" ===== TextTagTest for %s", path.c_str());
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053080 sp<android::FileSource> file = new FileSource(path.c_str());
81 ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
82
Harish Mahendrakard1056c22020-05-01 12:28:33 -070083 DataSourceHelper helper(file->wrap());
84 ID3 tag(&helper);
Neelkamal Semwal8776dd42019-11-26 10:21:10 +053085 ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
86 int countTextFrames = 0;
87 ID3::Iterator it(tag, nullptr);
Neelkamal Semwale821a502020-04-08 14:28:53 +053088 if (tag.version() != ID3::ID3_V1 && tag.version() != ID3::ID3_V1_1) {
89 while (!it.done()) {
90 String8 id;
91 it.getID(&id);
92 ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
93 if (id[0] == 'T') {
94 String8 text;
95 countTextFrames++;
96 it.getString(&text);
Tomasz Wasilczyk03fc55f2023-08-11 17:05:05 +000097 ALOGV("Found text frame %s : %s \n", id.c_str(), text.c_str());
Neelkamal Semwale821a502020-04-08 14:28:53 +053098 }
99 it.next();
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530100 }
Neelkamal Semwale821a502020-04-08 14:28:53 +0530101 } else {
102 while (!it.done()) {
103 String8 id;
104 String8 text;
105 it.getID(&id);
106 ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
107 it.getString(&text);
108 // if the tag has a value
Tomasz Wasilczyk03fc55f2023-08-11 17:05:05 +0000109 if (strcmp(text.c_str(), "")) {
Neelkamal Semwale821a502020-04-08 14:28:53 +0530110 countTextFrames++;
111 ALOGV("ID: %s\n", id.c_str());
Tomasz Wasilczyk03fc55f2023-08-11 17:05:05 +0000112 ALOGV("Text string: %s\n", text.c_str());
Neelkamal Semwale821a502020-04-08 14:28:53 +0530113 }
114 it.next();
115 }
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530116 }
117 ASSERT_EQ(countTextFrames, numTextFrames)
118 << "Expected " << numTextFrames << " text frames, found " << countTextFrames;
119}
120
121TEST_P(ID3albumArtTest, AlbumArtTest) {
122 bool albumArtPresent = GetParam().second;
123 string path = gEnv->getRes() + GetParam().first;
Ray Essick6626fd22021-04-28 19:08:44 -0700124 ALOGV(" ===== AlbumArt for %s", path.c_str());
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530125 sp<android::FileSource> file = new FileSource(path.c_str());
126 ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
127
Harish Mahendrakard1056c22020-05-01 12:28:33 -0700128 DataSourceHelper helper(file->wrap());
129 ID3 tag(&helper);
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530130 ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
131 size_t dataSize;
132 String8 mime;
133 const void *data = tag.getAlbumArt(&dataSize, &mime);
134
135 if (albumArtPresent) {
136 if (data) {
Tomasz Wasilczyk03fc55f2023-08-11 17:05:05 +0000137 ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.c_str());
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530138 }
Ray Essick0c89ab22020-04-25 13:00:09 -0700139 ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530140 } else {
141 ASSERT_EQ(data, nullptr) << "Found album art when expected none!";
142 }
Ray Essick6fd74092021-04-25 15:06:21 -0700143
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530144#if (LOG_NDEBUG == 0)
145 hexdump(data, dataSize > 128 ? 128 : dataSize);
146#endif
147}
148
149TEST_P(ID3multiAlbumArtTest, MultiAlbumArtTest) {
150 int numAlbumArt = GetParam().second;
151 string path = gEnv->getRes() + GetParam().first;
152 sp<android::FileSource> file = new FileSource(path.c_str());
153 ASSERT_EQ(file->initCheck(), (status_t)OK) << "File initialization failed! \n";
154
Harish Mahendrakard1056c22020-05-01 12:28:33 -0700155 DataSourceHelper helper(file->wrap());
156 ID3 tag(&helper);
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530157 ASSERT_TRUE(tag.isValid()) << "No valid ID3 tag found for " << path.c_str() << "\n";
158 int count = 0;
159 ID3::Iterator it(tag, nullptr);
160 while (!it.done()) {
161 String8 id;
162 it.getID(&id);
Neelkamal Semwale821a502020-04-08 14:28:53 +0530163 ASSERT_GT(id.length(), 0) << "Found an ID3 tag of 0 size";
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530164 // Check if the tag is an "APIC/PIC" tag.
165 if (String8(id) == "APIC" || String8(id) == "PIC") {
166 count++;
167 size_t dataSize;
168 String8 mime;
169 const void *data = tag.getAlbumArt(&dataSize, &mime);
170 if (data) {
Tomasz Wasilczyk03fc55f2023-08-11 17:05:05 +0000171 ALOGV("Found album art: size = %zu mime = %s \n", dataSize, mime.c_str());
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530172#if (LOG_NDEBUG == 0)
173 hexdump(data, dataSize > 128 ? 128 : dataSize);
174#endif
175 }
Ray Essick0c89ab22020-04-25 13:00:09 -0700176 ASSERT_NE(data, nullptr) << "Expected album art, found none! " << path;
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530177 }
178 it.next();
179 }
180 ASSERT_EQ(count, numAlbumArt) << "Found " << count << " album arts, expected " << numAlbumArt
181 << " album arts! \n";
182}
183
Ray Essick6626fd22021-04-28 19:08:44 -0700184// we have a test asset with large album art -- which is larger than our 3M cap
185// that we inserted intentionally in the ID3 parsing routine.
186// Rather than have it fail all the time, we have wrapped it under an #ifdef
187// so that the tests will pass.
188#undef TEST_LARGE
189
190
191// it appears that bbb_2sec_v24_unsynchronizedAllFrames.mp3 is not a legal file,
192// so we've commented it out of the list of files to be tested
193//
194
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530195INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3tagTest,
Neelkamal Semwale821a502020-04-08 14:28:53 +0530196 ::testing::Values("bbb_1sec_v23.mp3",
197 "bbb_1sec_1_image.mp3",
198 "bbb_1sec_2_image.mp3",
199 "bbb_2sec_v24.mp3",
200 "bbb_2sec_1_image.mp3",
201 "bbb_2sec_2_image.mp3",
202 "bbb_2sec_largeSize.mp3",
203 "bbb_1sec_v23_3tags.mp3",
204 "bbb_1sec_v1_5tags.mp3",
205 "bbb_2sec_v24_unsynchronizedOneFrame.mp3",
Ray Essick6fd74092021-04-25 15:06:21 -0700206 "idv24_unsynchronized.mp3"));
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530207
208INSTANTIATE_TEST_SUITE_P(
209 id3TestAll, ID3versionTest,
Neelkamal Semwale821a502020-04-08 14:28:53 +0530210 ::testing::Values(make_pair("bbb_1sec_v23.mp3", ID3::ID3_V2_3),
211 make_pair("bbb_1sec_1_image.mp3", ID3::ID3_V2_3),
212 make_pair("bbb_1sec_2_image.mp3", ID3::ID3_V2_3),
213 make_pair("bbb_2sec_v24.mp3", ID3::ID3_V2_4),
214 make_pair("bbb_2sec_1_image.mp3", ID3::ID3_V2_4),
215 make_pair("bbb_2sec_2_image.mp3", ID3::ID3_V2_4),
Ray Essick6626fd22021-04-28 19:08:44 -0700216#if TEST_LARGE
217 make_pair("bbb_2sec_largeSize.mp3", ID3::ID3_V2_4), // FAIL
218#endif
Neelkamal Semwale821a502020-04-08 14:28:53 +0530219 make_pair("bbb_1sec_v23_3tags.mp3", ID3::ID3_V2_3),
220 make_pair("bbb_1sec_v1_5tags.mp3", ID3::ID3_V1_1),
221 make_pair("bbb_1sec_v1_3tags.mp3", ID3::ID3_V1_1),
222 make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", ID3::ID3_V2_4),
Ray Essick6fd74092021-04-25 15:06:21 -0700223 make_pair("idv24_unsynchronized.mp3", ID3::ID3_V2_4)));
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530224
225INSTANTIATE_TEST_SUITE_P(
226 id3TestAll, ID3textTagTest,
Neelkamal Semwale821a502020-04-08 14:28:53 +0530227 ::testing::Values(
228 make_pair("bbb_1sec_v23.mp3", 1),
229 make_pair("bbb_1sec_1_image.mp3", 1),
230 make_pair("bbb_1sec_2_image.mp3", 1),
231 make_pair("bbb_2sec_v24.mp3", 1),
232 make_pair("bbb_2sec_1_image.mp3", 1),
233 make_pair("bbb_2sec_2_image.mp3", 1),
Ray Essick6626fd22021-04-28 19:08:44 -0700234#if TEST_LARGE
235 make_pair("bbb_2sec_largeSize.mp3", 1), // FAIL
236#endif
Neelkamal Semwale821a502020-04-08 14:28:53 +0530237 make_pair("bbb_1sec_v23_3tags.mp3", 3),
238 make_pair("bbb_1sec_v1_5tags.mp3", 5),
239 make_pair("bbb_1sec_v1_3tags.mp3", 3),
Ray Essick6626fd22021-04-28 19:08:44 -0700240 make_pair("bbb_2sec_v24_unsynchronizedOneFrame.mp3", 3)
241 ));
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530242
Neelkamal Semwale821a502020-04-08 14:28:53 +0530243INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3albumArtTest,
244 ::testing::Values(make_pair("bbb_1sec_v23.mp3", false),
245 make_pair("bbb_1sec_1_image.mp3", true),
246 make_pair("bbb_1sec_2_image.mp3", true),
247 make_pair("bbb_2sec_v24.mp3", false),
248 make_pair("bbb_2sec_1_image.mp3", true),
249 make_pair("bbb_2sec_2_image.mp3", true),
Ray Essick6626fd22021-04-28 19:08:44 -0700250#if TEST_LARGE
251 make_pair("bbb_2sec_largeSize.mp3", true), // FAIL
252#endif
Ray Essick6fd74092021-04-25 15:06:21 -0700253 make_pair("bbb_1sec_v1_5tags.mp3", false),
254 make_pair("idv24_unsynchronized.mp3", true)
255 ));
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530256
Neelkamal Semwale821a502020-04-08 14:28:53 +0530257INSTANTIATE_TEST_SUITE_P(id3TestAll, ID3multiAlbumArtTest,
258 ::testing::Values(make_pair("bbb_1sec_v23.mp3", 0),
259 make_pair("bbb_2sec_v24.mp3", 0),
Ray Essick6626fd22021-04-28 19:08:44 -0700260#if TEST_LARGE
261 make_pair("bbb_2sec_largeSize.mp3", 3), // FAIL
262#endif
Neelkamal Semwale821a502020-04-08 14:28:53 +0530263 make_pair("bbb_1sec_1_image.mp3", 1),
264 make_pair("bbb_2sec_1_image.mp3", 1),
265 make_pair("bbb_1sec_2_image.mp3", 2),
Ray Essick6626fd22021-04-28 19:08:44 -0700266 make_pair("bbb_2sec_2_image.mp3", 2)
267 ));
Neelkamal Semwal8776dd42019-11-26 10:21:10 +0530268
269int main(int argc, char **argv) {
270 gEnv = new ID3TestEnvironment();
271 ::testing::AddGlobalTestEnvironment(gEnv);
272 ::testing::InitGoogleTest(&argc, argv);
273 int status = gEnv->initFromOptions(argc, argv);
274 if (status == 0) {
275 status = RUN_ALL_TESTS();
276 ALOGI("ID3 Test result = %d\n", status);
277 }
278 return status;
279}