1 /*
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 "decoderTest"
19
20 #include <fstream>
21 #include <iostream>
22 #include <limits>
23 #include <memory>
24
25 #include <android/binder_process.h>
26
27 #include "BenchmarkTestEnvironment.h"
28 #include "Decoder.h"
29
30 static BenchmarkTestEnvironment *gEnv = nullptr;
31
32 class DecoderTest : public ::testing::TestWithParam<tuple<string, string, bool>> {};
33
TEST_P(DecoderTest,Decode)34 TEST_P(DecoderTest, Decode) {
35 ALOGV("Decode the samples given by extractor");
36 tuple<string /* InputFile */, string /* CodecName */, bool /* asyncMode */> params = GetParam();
37
38 string inputFile = gEnv->getRes() + get<0>(params);
39 FILE *inputFp = fopen(inputFile.c_str(), "rb");
40 ASSERT_NE(inputFp, nullptr) << "Unable to open " << inputFile << " file for reading";
41
42 std::unique_ptr<Decoder> decoder(new (std::nothrow) Decoder());
43 ASSERT_NE(decoder, nullptr) << "Decoder creation failed";
44
45 Extractor *extractor = decoder->getExtractor();
46 ASSERT_NE(extractor, nullptr) << "Extractor creation failed";
47
48 // Read file properties
49 struct stat buf;
50 stat(inputFile.c_str(), &buf);
51 size_t fileSize = buf.st_size;
52 int32_t fd = fileno(inputFp);
53
54 int32_t trackCount = extractor->initExtractor(fd, fileSize);
55 ASSERT_GT(trackCount, 0) << "initExtractor failed";
56
57 for (int curTrack = 0; curTrack < trackCount; curTrack++) {
58 int32_t status = extractor->setupTrackFormat(curTrack);
59 ASSERT_EQ(status, 0) << "Track Format invalid";
60
61 std::unique_ptr<uint8_t[]> inputBuffer(new (std::nothrow) uint8_t[kMaxBufferSize]);
62 ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
63
64 vector<AMediaCodecBufferInfo> frameInfo;
65 AMediaCodecBufferInfo info;
66 uint32_t inputBufferOffset = 0;
67
68 // Get frame data
69 while (1) {
70 status = extractor->getFrameSample(info);
71 if (status || !info.size) break;
72 // copy the meta data and buffer to be passed to decoder
73 ASSERT_LE(inputBufferOffset + info.size, kMaxBufferSize)
74 << "Memory allocated not sufficient";
75
76 memcpy(inputBuffer.get() + inputBufferOffset, extractor->getFrameBuf(), info.size);
77 frameInfo.push_back(info);
78 inputBufferOffset += info.size;
79 }
80
81 string codecName = get<1>(params);
82 bool asyncMode = get<2>(params);
83 decoder->setupDecoder();
84 status = decoder->decode(inputBuffer.get(), frameInfo, codecName, asyncMode);
85 ASSERT_EQ(status, AMEDIA_OK) << "Decoder failed for " << codecName;
86
87 decoder->deInitCodec();
88 ALOGV("codec : %s", codecName.c_str());
89 string inputReference = get<0>(params);
90 decoder->dumpStatistics(inputReference, codecName, (asyncMode ? "async" : "sync"),
91 gEnv->getStatsFile());
92 decoder->resetDecoder();
93 }
94 fclose(inputFp);
95 extractor->deInitExtractor();
96 }
97
98 // TODO: (b/140549596)
99 // Add wav files
100 INSTANTIATE_TEST_SUITE_P(
101 AudioDecoderSyncTest, DecoderTest,
102 ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", false),
103 make_tuple("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", "", false),
104 make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", false),
105 make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", false),
106 make_tuple("bbb_44100hz_2ch_80kbps_vorbis_30sec.webm", "", false),
107 make_tuple("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "", false),
108 make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", false)));
109
110 INSTANTIATE_TEST_SUITE_P(
111 AudioDecoderAsyncTest, DecoderTest,
112 ::testing::Values(make_tuple("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "", true),
113 make_tuple("bbb_44100hz_2ch_128kbps_mp3_30sec.mp3", "", true),
114 make_tuple("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "", true),
115 make_tuple("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "", true),
116 make_tuple("bbb_44100hz_2ch_80kbps_vorbis_30sec.webm", "", true),
117 make_tuple("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "", true),
118 make_tuple("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "", true)));
119
120 INSTANTIATE_TEST_SUITE_P(VideDecoderSyncTest, DecoderTest,
121 ::testing::Values(
122 // Hardware codecs
123 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm", "", false),
124 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", false),
125 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm", "", false),
126 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", "", false),
127 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "", false),
128 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp", "", false),
129 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", false),
130 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", false),
131 // Software codecs
132 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
133 "c2.android.vp9.decoder", false),
134 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
135 "c2.android.vp8.decoder", false),
136 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm",
137 "c2.android.av1.decoder", false),
138 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4",
139 "c2.android.mpeg2.decoder", false),
140 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4",
141 "c2.android.mpeg4.decoder", false),
142 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp",
143 "c2.android.h263.decoder", false),
144 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
145 "c2.android.avc.decoder", false),
146 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
147 "c2.android.hevc.decoder", false)));
148
149 INSTANTIATE_TEST_SUITE_P(VideoDecoderAsyncTest, DecoderTest,
150 ::testing::Values(
151 // Hardware codecs
152 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm", "", true),
153 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm", "", true),
154 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm", "", true),
155 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4", "", true),
156 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4", "", true),
157 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp", "", true),
158 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts", "", true),
159 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv", "", true),
160 // Software codecs
161 make_tuple("crowd_1920x1080_25fps_4000kbps_vp9.webm",
162 "c2.android.vp9.decoder", true),
163 make_tuple("crowd_1920x1080_25fps_4000kbps_vp8.webm",
164 "c2.android.vp8.decoder", true),
165 make_tuple("crowd_1920x1080_25fps_4000kbps_av1.webm",
166 "c2.android.av1.decoder", true),
167 make_tuple("crowd_1920x1080_25fps_7300kbps_mpeg2.mp4",
168 "c2.android.mpeg2.decoder", true),
169 make_tuple("crowd_1920x1080_25fps_6000kbps_mpeg4.mp4",
170 "c2.android.mpeg4.decoder", true),
171 make_tuple("crowd_352x288_25fps_6000kbps_h263.3gp",
172 "c2.android.h263.decoder", true),
173 make_tuple("crowd_1920x1080_25fps_6700kbps_h264.ts",
174 "c2.android.avc.decoder", true),
175 make_tuple("crowd_1920x1080_25fps_4000kbps_h265.mkv",
176 "c2.android.hevc.decoder", true)));
177
main(int argc,char ** argv)178 int main(int argc, char **argv) {
179 ABinderProcess_startThreadPool();
180 gEnv = new (std::nothrow) BenchmarkTestEnvironment();
181 ::testing::AddGlobalTestEnvironment(gEnv);
182 ::testing::InitGoogleTest(&argc, argv);
183 int status = gEnv->initFromOptions(argc, argv);
184 if (status == 0) {
185 gEnv->setStatsFile("Decoder.csv");
186 status = gEnv->writeStatsHeader();
187 ALOGV("Stats file = %d\n", status);
188 status = RUN_ALL_TESTS();
189 ALOGV("Decoder Test result = %d\n", status);
190 }
191 return status;
192 }
193