1 /*
2  * Copyright (C) 2020 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 "MetaDataUtilsTest"
19 #include <utils/Log.h>
20 
21 #include <fstream>
22 #include <memory>
23 #include <string>
24 
25 #include <media/esds/ESDS.h>
26 #include <media/NdkMediaFormat.h>
27 #include <media/stagefright/MediaCodecConstants.h>
28 #include <media/stagefright/MediaDefs.h>
29 #include <media/stagefright/MetaDataBase.h>
30 #include <media/stagefright/MetaDataUtils.h>
31 #include <media/stagefright/foundation/ABitReader.h>
32 
33 #include "MetaDataUtilsTestEnvironment.h"
34 
35 constexpr uint8_t kAdtsCsdSize = 7;
36 // from AAC specs: https://www.iso.org/standard/43345.html
37 constexpr int32_t kSamplingFreq[] = {96000, 88200, 64000, 48000, 44100, 32000,
38                                      24000, 22050, 16000, 12000, 11025, 8000};
39 constexpr uint8_t kMaxSamplingFreqIndex = sizeof(kSamplingFreq) / sizeof(kSamplingFreq[0]);
40 
41 static MetaDataUtilsTestEnvironment *gEnv = nullptr;
42 
43 using namespace android;
44 
45 class MetaDataValidate {
46   public:
MetaDataValidate()47     MetaDataValidate() : mInputBuffer(nullptr) {}
48 
~MetaDataValidate()49     ~MetaDataValidate() {
50         if (mInputBuffer) {
51             delete[] mInputBuffer;
52             mInputBuffer = nullptr;
53         }
54     }
55 
SetUpMetaDataValidate(string fileName)56     void SetUpMetaDataValidate(string fileName) {
57         struct stat buf;
58         int8_t err = stat(fileName.c_str(), &buf);
59         ASSERT_EQ(err, 0) << "Failed to get file information for file: " << fileName;
60 
61         mInputBufferSize = buf.st_size;
62         FILE *inputFilePtr = fopen(fileName.c_str(), "rb+");
63         ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << fileName;
64 
65         mInputBuffer = new uint8_t[mInputBufferSize];
66         ASSERT_NE(mInputBuffer, nullptr)
67                 << "Failed to allocate memory of size: " << mInputBufferSize;
68 
69         int32_t numBytes =
70                 fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
71         ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";
72 
73         fclose(inputFilePtr);
74     }
75 
76     size_t mInputBufferSize;
77     const uint8_t *mInputBuffer;
78 };
79 
80 class AvcCSDTest : public ::testing::TestWithParam<
81                            tuple<string /*inputFile*/, size_t /*avcWidth*/, size_t /*avcHeight*/>> {
82   public:
AvcCSDTest()83     AvcCSDTest() : mInputBuffer(nullptr) {}
84 
~AvcCSDTest()85     ~AvcCSDTest() {
86         if (mInputBuffer) {
87             delete[] mInputBuffer;
88             mInputBuffer = nullptr;
89         }
90     }
SetUp()91     virtual void SetUp() override {
92         tuple<string, size_t, size_t> params = GetParam();
93         string inputFile = gEnv->getRes() + get<0>(params);
94         mFrameWidth = get<1>(params);
95         mFrameHeight = get<2>(params);
96 
97         struct stat buf;
98         int8_t err = stat(inputFile.c_str(), &buf);
99         ASSERT_EQ(err, 0) << "Failed to get information for file: " << inputFile;
100 
101         mInputBufferSize = buf.st_size;
102         FILE *inputFilePtr = fopen(inputFile.c_str(), "rb+");
103         ASSERT_NE(inputFilePtr, nullptr) << "Failed to open file: " << inputFile;
104 
105         mInputBuffer = new uint8_t[mInputBufferSize];
106         ASSERT_NE(mInputBuffer, nullptr)
107                 << "Failed to create a buffer of size: " << mInputBufferSize;
108 
109         int32_t numBytes =
110                 fread((char *)mInputBuffer, sizeof(uint8_t), mInputBufferSize, inputFilePtr);
111         ASSERT_EQ(numBytes, mInputBufferSize) << numBytes << " of " << mInputBufferSize << " read";
112 
113         fclose(inputFilePtr);
114     }
115 
116     size_t mFrameWidth;
117     size_t mFrameHeight;
118     size_t mInputBufferSize;
119     const uint8_t *mInputBuffer;
120 };
121 
122 class AvcCSDValidateTest : public MetaDataValidate,
123                            public ::testing::TestWithParam<string /*inputFile*/> {
124   public:
SetUp()125     virtual void SetUp() override {
126         string inputFile = gEnv->getRes() + GetParam();
127 
128         ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
129     }
130 };
131 
132 class AacCSDTest
133     : public ::testing::TestWithParam<tuple<uint32_t /*profile*/, uint32_t /*samplingFreqIndex*/,
134                                             uint32_t /*channelConfig*/>> {
135   public:
SetUp()136     virtual void SetUp() override {
137         tuple<uint32_t, uint32_t, uint32_t> params = GetParam();
138         mAacProfile = get<0>(params);
139         mAacSamplingFreqIndex = get<1>(params);
140         mAacChannelConfig = get<2>(params);
141     }
142 
143     uint32_t mAacProfile;
144     uint32_t mAacSamplingFreqIndex;
145     uint32_t mAacChannelConfig;
146 };
147 
148 class AacADTSTest
149     : public ::testing::TestWithParam<
150               tuple<string /*adtsFile*/, uint32_t /*channelCount*/, uint32_t /*sampleRate*/>> {
151   public:
AacADTSTest()152     AacADTSTest() : mInputBuffer(nullptr) {}
153 
SetUp()154     virtual void SetUp() override {
155         tuple<string, uint32_t, uint32_t> params = GetParam();
156         string fileName = gEnv->getRes() + get<0>(params);
157         mAacChannelCount = get<1>(params);
158         mAacSampleRate = get<2>(params);
159 
160         FILE *filePtr = fopen(fileName.c_str(), "r");
161         ASSERT_NE(filePtr, nullptr) << "Failed to open file: " << fileName;
162 
163         mInputBuffer = new uint8_t[kAdtsCsdSize];
164         ASSERT_NE(mInputBuffer, nullptr) << "Failed to allocate a memory of size: " << kAdtsCsdSize;
165 
166         int32_t numBytes = fread((void *)mInputBuffer, sizeof(uint8_t), kAdtsCsdSize, filePtr);
167         ASSERT_EQ(numBytes, kAdtsCsdSize)
168                 << "Failed to read complete file, bytes read: " << numBytes;
169 
170         fclose(filePtr);
171     }
172     int32_t mAacChannelCount;
173     int32_t mAacSampleRate;
174     const uint8_t *mInputBuffer;
175 };
176 
177 class AacCSDValidateTest : public MetaDataValidate,
178                            public ::testing::TestWithParam<string /*inputFile*/> {
179   public:
SetUp()180     virtual void SetUp() override {
181         string inputFile = gEnv->getRes() + GetParam();
182 
183         ASSERT_NO_FATAL_FAILURE(SetUpMetaDataValidate(inputFile));
184     }
185 };
186 
187 class VorbisTest : public ::testing::TestWithParam<pair<string /*fileName*/, string /*infoFile*/>> {
188   public:
SetUp()189     virtual void SetUp() override {
190         pair<string, string> params = GetParam();
191         string inputMediaFile = gEnv->getRes() + params.first;
192         mInputFileStream.open(inputMediaFile, ifstream::in);
193         ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputMediaFile;
194 
195         string inputInfoFile = gEnv->getRes() + params.second;
196         mInfoFileStream.open(inputInfoFile, ifstream::in);
197         ASSERT_TRUE(mInputFileStream.is_open()) << "Failed to open data file: " << inputInfoFile;
198         ASSERT_FALSE(inputInfoFile.empty()) << "Empty info file: " << inputInfoFile;
199     }
200 
~VorbisTest()201     ~VorbisTest() {
202         if (mInputFileStream.is_open()) mInputFileStream.close();
203         if (mInfoFileStream.is_open()) mInfoFileStream.close();
204     }
205 
206     ifstream mInputFileStream;
207     ifstream mInfoFileStream;
208 };
209 
TEST_P(AvcCSDTest,AvcCSDValidationTest)210 TEST_P(AvcCSDTest, AvcCSDValidationTest) {
211     AMediaFormat *csdData = AMediaFormat_new();
212     ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
213 
214     bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
215     ASSERT_TRUE(status) << "Failed to make AVC CSD from AMediaFormat";
216 
217     int32_t avcWidth = -1;
218     status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_WIDTH, &avcWidth);
219     ASSERT_TRUE(status) << "Failed to get avc width";
220     ASSERT_EQ(avcWidth, mFrameWidth);
221 
222     int32_t avcHeight = -1;
223     status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_HEIGHT, &avcHeight);
224     ASSERT_TRUE(status) << "Failed to get avc height";
225     ASSERT_EQ(avcHeight, mFrameHeight);
226 
227     const char *mimeType = "";
228     status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
229     ASSERT_TRUE(status) << "Failed to get the mime type";
230     ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_VIDEO_AVC);
231 
232     std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
233     ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
234 
235     status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
236     ASSERT_TRUE(status) << "Failed to make AVC CSD from MetaDataBase";
237 
238     avcWidth = -1;
239     status = metaData->findInt32(kKeyWidth, &avcWidth);
240     ASSERT_TRUE(status) << "Failed to find the width";
241     ASSERT_EQ(avcWidth, mFrameWidth);
242 
243     avcHeight = -1;
244     status = metaData->findInt32(kKeyHeight, &avcHeight);
245     ASSERT_TRUE(status) << "Failed to find the height";
246     ASSERT_EQ(avcHeight, mFrameHeight);
247 
248     void *csdAMediaFormatBuffer = nullptr;
249     size_t csdAMediaFormatSize;
250     status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_AVC, &csdAMediaFormatBuffer,
251                                     &csdAMediaFormatSize);
252     ASSERT_TRUE(status) << "Failed to get the CSD from AMediaFormat";
253     ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD from AMediaFormat";
254 
255     const void *csdMetaDataBaseBuffer = nullptr;
256     size_t csdMetaDataBaseSize = 0;
257     uint32_t mediaType;
258     status = metaData->findData(kKeyAVCC, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
259     ASSERT_TRUE(status) << "Failed to get the CSD from MetaDataBase";
260     ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD from MetaDataBase";
261     ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
262     ASSERT_EQ(csdMetaDataBaseSize, csdAMediaFormatSize)
263             << "CSD size of MetaData type and AMediaFormat type must be same";
264 
265     int32_t result = memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
266     ASSERT_EQ(result, 0) << "CSD from AMediaFormat and MetaDataBase do not match";
267 
268     AMediaFormat_delete(csdData);
269 }
270 
TEST_P(AvcCSDValidateTest,AvcValidateTest)271 TEST_P(AvcCSDValidateTest, AvcValidateTest) {
272     AMediaFormat *csdData = AMediaFormat_new();
273     ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
274 
275     bool status = MakeAVCCodecSpecificData(csdData, mInputBuffer, mInputBufferSize);
276     ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with AMediaFormat succeeds with invalid data";
277 
278     std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
279     ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
280 
281     status = MakeAVCCodecSpecificData(*metaData, mInputBuffer, mInputBufferSize);
282     ASSERT_FALSE(status) << "MakeAVCCodecSpecificData with MetaDataBase succeeds with invalid data";
283 }
284 
TEST_P(AacCSDTest,AacCSDValidationTest)285 TEST_P(AacCSDTest, AacCSDValidationTest) {
286     AMediaFormat *csdData = AMediaFormat_new();
287     ASSERT_NE(csdData, nullptr) << "Failed to create AMedia format";
288 
289     ASSERT_GE(mAacSamplingFreqIndex, 0);
290     ASSERT_LT(mAacSamplingFreqIndex, kMaxSamplingFreqIndex);
291     bool status = MakeAACCodecSpecificData(csdData, mAacProfile, mAacSamplingFreqIndex,
292                                            mAacChannelConfig);
293     ASSERT_TRUE(status) << "Failed to make AAC CSD from AMediaFormat";
294 
295     int32_t sampleRate = -1;
296     status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_SAMPLE_RATE, &sampleRate);
297     ASSERT_TRUE(status) << "Failed to get sample rate";
298     ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);
299 
300     int32_t channelCount = -1;
301     status = AMediaFormat_getInt32(csdData, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &channelCount);
302     ASSERT_TRUE(status) << "Failed to get channel count";
303     ASSERT_EQ(channelCount, mAacChannelConfig);
304 
305     const char *mimeType = "";
306     status = AMediaFormat_getString(csdData, AMEDIAFORMAT_KEY_MIME, &mimeType);
307     ASSERT_TRUE(status) << "Failed to get the mime type";
308     ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
309 
310     std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
311     ASSERT_NE(metaData, nullptr) << "Failed to create MetaData Base";
312 
313     status = MakeAACCodecSpecificData(*metaData, mAacProfile, mAacSamplingFreqIndex,
314                                       mAacChannelConfig);
315     ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";
316 
317     sampleRate = -1;
318     status = metaData->findInt32(kKeySampleRate, &sampleRate);
319     ASSERT_TRUE(status) << "Failed to get sampling rate";
320     ASSERT_EQ(kSamplingFreq[mAacSamplingFreqIndex], sampleRate);
321 
322     channelCount = -1;
323     status = metaData->findInt32(kKeyChannelCount, &channelCount);
324     ASSERT_TRUE(status) << "Failed to get channel count";
325     ASSERT_EQ(channelCount, mAacChannelConfig);
326 
327     mimeType = "";
328     status = metaData->findCString(kKeyMIMEType, &mimeType);
329     ASSERT_TRUE(status) << "Failed to get mime type";
330     ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
331 
332     void *csdAMediaFormatBuffer = nullptr;
333     size_t csdAMediaFormatSize = 0;
334     status = AMediaFormat_getBuffer(csdData, AMEDIAFORMAT_KEY_CSD_0, &csdAMediaFormatBuffer,
335                                     &csdAMediaFormatSize);
336     ASSERT_TRUE(status) << "Failed to get the AMediaFormat CSD";
337     ASSERT_GT(csdAMediaFormatSize, 0) << "CSD size must be greater than 0";
338     ASSERT_NE(csdAMediaFormatBuffer, nullptr) << "Invalid CSD found";
339 
340     const void *csdMetaDataBaseBuffer;
341     size_t csdMetaDataBaseSize = 0;
342     uint32_t mediaType;
343     status = metaData->findData(kKeyESDS, &mediaType, &csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
344     ASSERT_TRUE(status) << "Failed to get the ESDS data from MetaDataBase";
345     ASSERT_GT(csdMetaDataBaseSize, 0) << "CSD size must be greater than 0";
346 
347     ESDS esds(csdMetaDataBaseBuffer, csdMetaDataBaseSize);
348     status_t result = esds.getCodecSpecificInfo(&csdMetaDataBaseBuffer, &csdMetaDataBaseSize);
349     ASSERT_EQ(result, (status_t)OK) << "Failed to get CSD from ESDS data";
350     ASSERT_NE(csdMetaDataBaseBuffer, nullptr) << "Invalid CSD found";
351     ASSERT_EQ(csdAMediaFormatSize, csdMetaDataBaseSize)
352             << "CSD size do not match between AMediaFormat type and MetaDataBase type";
353 
354     int32_t memcmpResult =
355             memcmp(csdAMediaFormatBuffer, csdMetaDataBaseBuffer, csdAMediaFormatSize);
356     ASSERT_EQ(memcmpResult, 0) << "AMediaFormat and MetaDataBase CSDs do not match";
357 
358     AMediaFormat_delete(csdData);
359 }
360 
TEST_P(AacADTSTest,AacADTSValidationTest)361 TEST_P(AacADTSTest, AacADTSValidationTest) {
362     std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
363     ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
364 
365     bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
366     ASSERT_TRUE(status) << "Failed to make AAC CSD from MetaDataBase";
367 
368     int32_t sampleRate = -1;
369     status = metaData->findInt32(kKeySampleRate, &sampleRate);
370     ASSERT_TRUE(status) << "Failed to get sampling rate";
371     ASSERT_EQ(sampleRate, mAacSampleRate);
372 
373     int32_t channelCount = -1;
374     status = metaData->findInt32(kKeyChannelCount, &channelCount);
375     ASSERT_TRUE(status) << "Failed to get channel count";
376     ASSERT_EQ(channelCount, mAacChannelCount);
377 
378     const char *mimeType = "";
379     status = metaData->findCString(kKeyMIMEType, &mimeType);
380     ASSERT_TRUE(status) << "Failed to get mime type";
381     ASSERT_STREQ(mimeType, MEDIA_MIMETYPE_AUDIO_AAC);
382 }
383 
TEST_P(AacCSDValidateTest,AacInvalidInputTest)384 TEST_P(AacCSDValidateTest, AacInvalidInputTest) {
385     std::unique_ptr<MetaDataBase> metaData(new MetaDataBase());
386     ASSERT_NE(metaData, nullptr) << "Failed to create meta data";
387 
388     bool status = MakeAACCodecSpecificData(*metaData, mInputBuffer, kAdtsCsdSize);
389     ASSERT_FALSE(status) << "MakeAACCodecSpecificData succeeds with invalid data";
390 }
391 
TEST_P(VorbisTest,VorbisCommentTest)392 TEST_P(VorbisTest, VorbisCommentTest) {
393     string line;
394     string tag;
395     string key;
396     string value;
397     size_t commentLength;
398     bool status;
399 
400     while (getline(mInfoFileStream, line)) {
401         istringstream stringLine(line);
402         stringLine >> tag >> key >> value >> commentLength;
403         ASSERT_GT(commentLength, 0) << "Vorbis comment size must be greater than 0";
404 
405         string comment;
406         string dataLine;
407 
408         getline(mInputFileStream, dataLine);
409         istringstream dataStringLine(dataLine);
410         dataStringLine >> comment;
411 
412         std::unique_ptr<char[]> buffer(new char[commentLength]);
413         ASSERT_NE(buffer, nullptr) << "Failed to allocate buffer of size: " << commentLength;
414         strncpy(buffer.get(), comment.c_str(), commentLength);
415 
416         AMediaFormat *fileMeta = AMediaFormat_new();
417         ASSERT_NE(fileMeta, nullptr) << "Failed to create AMedia format";
418 
419         parseVorbisComment(fileMeta, buffer.get(), commentLength);
420 
421         if (!strncasecmp(tag.c_str(), "ANDROID_HAPTIC", sizeof(tag))) {
422             int32_t numChannelExpected = stoi(value);
423             int32_t numChannelFound = -1;
424             status = AMediaFormat_getInt32(fileMeta, key.c_str(), &numChannelFound);
425             ASSERT_TRUE(status) << "Failed to get the channel count";
426             ASSERT_EQ(numChannelExpected, numChannelFound);
427         } else if (!strncasecmp(tag.c_str(), "ANDROID_LOOP", sizeof(tag))) {
428             int32_t loopExpected = !value.compare("true");
429             int32_t loopFound = -1;
430 
431             status = AMediaFormat_getInt32(fileMeta, "loop", &loopFound);
432             ASSERT_TRUE(status) << "Failed to get the loop count";
433             ASSERT_EQ(loopExpected, loopFound);
434         } else {
435             const char *tagValue = "";
436             status = AMediaFormat_getString(fileMeta, key.c_str(), &tagValue);
437             ASSERT_TRUE(status) << "Failed to get the tag value";
438             ASSERT_STREQ(value.c_str(), tagValue);
439         }
440         AMediaFormat_delete(fileMeta);
441     }
442 }
443 
444 INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDTest,
445                          ::testing::Values(make_tuple("sps_pps_userdata.h264", 8, 8),
446                                            make_tuple("sps_userdata_pps.h264", 8, 8),
447                                            make_tuple("sps_pps_sps_pps.h264", 8, 8)));
448 
449 // TODO(b/158067691): Add invalid test vectors with incomplete PPS or no PPS
450 INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AvcCSDValidateTest,
451                          ::testing::Values("sps_pps_only_startcode.h264",
452                                            "sps_incomplete_pps.h264",
453                                            // TODO(b/158067691) "sps_pps_incomplete.h264",
454                                            "randomdata.h264",
455                                            // TODO(b/158067691) "sps.h264",
456                                            "pps.h264"));
457 
458 INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDTest,
459                          ::testing::Values(make_tuple(AACObjectMain, 1, 1)));
460 
461 INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacADTSTest,
462                          ::testing::Values(make_tuple("loudsoftaacadts", 1, 44100)));
463 
464 INSTANTIATE_TEST_SUITE_P(MetaDataUtilsTestAll, AacCSDValidateTest,
465                          ::testing::Values("loudsoftaacadts_invalidheader",
466                                            "loudsoftaacadts_invalidprofile",
467                                            "loudsoftaacadts_invalidchannelconfig"));
468 
469 // TODO(b/157974508) Add test vector for vorbis thumbnail tag
470 // Info file contains TAG, Key, Value and size of the vorbis comment
471 INSTANTIATE_TEST_SUITE_P(
472         MetaDataUtilsTestAll, VorbisTest,
473         ::testing::Values(make_pair("vorbiscomment_sintel.dat", "vorbiscomment_sintel.info"),
474                           make_pair("vorbiscomment_album.dat", "vorbiscomment_album.info"),
475                           make_pair("vorbiscomment_loop.dat", "vorbiscomment_loop.info")));
476 
main(int argc,char ** argv)477 int main(int argc, char **argv) {
478     gEnv = new MetaDataUtilsTestEnvironment();
479     ::testing::AddGlobalTestEnvironment(gEnv);
480     ::testing::InitGoogleTest(&argc, argv);
481     int status = gEnv->initFromOptions(argc, argv);
482     if (status == 0) {
483         status = RUN_ALL_TESTS();
484         ALOGV("Test result = %d\n", status);
485     }
486     return status;
487 }
488