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