blob: 98eb17a6fb1aba65af4bc880f4e8906bae0491ac [file] [log] [blame]
Manisha Jajoo19492a02019-10-14 16:38:17 +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 "C2EncoderTest"
19
Manisha Jajoo19492a02019-10-14 16:38:17 +053020#include <fstream>
21#include <iostream>
22#include <limits>
23
24#include "BenchmarkTestEnvironment.h"
25#include "C2Encoder.h"
26#include "Decoder.h"
27
28static BenchmarkTestEnvironment *gEnv = nullptr;
29
30class C2EncoderTest : public ::testing::TestWithParam<pair<string, string>> {
31 public:
Manisha Jajoo2d931a82019-12-20 15:49:52 +053032 C2EncoderTest() : mEncoder(nullptr) {}
33
34 ~C2EncoderTest() {
35 if (!mCodecList.empty()) {
36 mCodecList.clear();
37 }
38 if (mEncoder) {
39 delete mEncoder;
40 mEncoder = nullptr;
41 }
42 }
43
44 virtual void SetUp() override { setupC2EncoderTest(); }
Manisha Jajoo19492a02019-10-14 16:38:17 +053045
46 void setupC2EncoderTest();
47
48 vector<string> mCodecList;
49 C2Encoder *mEncoder;
50};
51
52void C2EncoderTest::setupC2EncoderTest() {
53 mEncoder = new C2Encoder();
54 ASSERT_NE(mEncoder, nullptr) << "C2Encoder creation failed";
55
56 int32_t status = mEncoder->setupCodec2();
57 ASSERT_EQ(status, 0) << "Codec2 setup failed";
58
59 mCodecList = mEncoder->getSupportedComponentList(true /* isEncoder*/);
60 ASSERT_GT(mCodecList.size(), 0) << "Codec2 client didn't recognise any component";
61}
62
63TEST_P(C2EncoderTest, Codec2Encode) {
64 ALOGV("Encodes the input using codec2 framework");
65 string inputFile = gEnv->getRes() + GetParam().first;
66 FILE *inputFp = fopen(inputFile.c_str(), "rb");
67 ASSERT_NE(inputFp, nullptr) << "Unable to open input file for reading";
68
69 Decoder *decoder = new Decoder();
70 ASSERT_NE(decoder, nullptr) << "Decoder creation failed";
71
72 Extractor *extractor = decoder->getExtractor();
73 ASSERT_NE(extractor, nullptr) << "Extractor creation failed";
74
75 // Read file properties
76 struct stat buf;
77 stat(inputFile.c_str(), &buf);
78 size_t fileSize = buf.st_size;
79 int32_t fd = fileno(inputFp);
80
81 ASSERT_LE(fileSize, kMaxBufferSize)
82 << "Input file size is greater than the threshold memory dedicated to the test";
83
84 int32_t trackCount = extractor->initExtractor(fd, fileSize);
85 ASSERT_GT(trackCount, 0) << "initExtractor failed";
86
87 for (int curTrack = 0; curTrack < trackCount; curTrack++) {
88 int32_t status = extractor->setupTrackFormat(curTrack);
89 ASSERT_EQ(status, 0) << "Track Format invalid";
90
91 uint8_t *inputBuffer = (uint8_t *)malloc(fileSize);
92 ASSERT_NE(inputBuffer, nullptr) << "Insufficient memory";
93
94 vector<AMediaCodecBufferInfo> frameInfo;
95 AMediaCodecBufferInfo info;
96 uint32_t inputBufferOffset = 0;
97
98 // Get frame data
99 while (1) {
100 status = extractor->getFrameSample(info);
101 if (status || !info.size) break;
102 // copy the meta data and buffer to be passed to decoder
103 ASSERT_LE(inputBufferOffset + info.size, fileSize) << "Memory allocated not sufficient";
104
105 memcpy(inputBuffer + inputBufferOffset, extractor->getFrameBuf(), info.size);
106 frameInfo.push_back(info);
107 inputBufferOffset += info.size;
108 }
109
110 string decName = "";
111 string outputFileName = "decode.out";
112 FILE *outFp = fopen(outputFileName.c_str(), "wb");
113 ASSERT_NE(outFp, nullptr) << "Unable to open output file" << outputFileName
114 << " for dumping decoder's output";
115
116 decoder->setupDecoder();
117 status = decoder->decode(inputBuffer, frameInfo, decName, false /*asyncMode */, outFp);
118 ASSERT_EQ(status, AMEDIA_OK) << "Decode returned error : " << status;
119
120 // Encode the given input stream for all C2 codecs supported by device
121 AMediaFormat *format = extractor->getFormat();
122 ifstream eleStream;
123 eleStream.open(outputFileName.c_str(), ifstream::binary | ifstream::ate);
124 ASSERT_EQ(eleStream.is_open(), true) << outputFileName.c_str() << " - file not found";
125 size_t eleSize = eleStream.tellg();
126
127 for (string codecName : mCodecList) {
128 if (codecName.find(GetParam().second) != string::npos) {
129 status = mEncoder->createCodec2Component(codecName, format);
130 ASSERT_EQ(status, 0) << "Create component failed for " << codecName;
131
132 // Send the inputs to C2 Encoder and wait till all buffers are returned.
133 eleStream.seekg(0, ifstream::beg);
134 status = mEncoder->encodeFrames(eleStream, eleSize);
135 ASSERT_EQ(status, 0) << "Encoder failed for " << codecName;
136
137 mEncoder->waitOnInputConsumption();
138 ASSERT_TRUE(mEncoder->mEos) << "Test Failed. Didn't receive EOS \n";
139
140 mEncoder->deInitCodec();
141 int64_t durationUs = extractor->getClipDuration();
Manisha Jajoo2d931a82019-12-20 15:49:52 +0530142 ALOGV("codec : %s", codecName.c_str());
Manisha Jajoo19492a02019-10-14 16:38:17 +0530143 mEncoder->dumpStatistics(GetParam().first, durationUs);
144 mEncoder->resetEncoder();
145 }
146 }
147
148 // Destroy the decoder for the given input
149 decoder->deInitCodec();
150 decoder->resetDecoder();
151 free(inputBuffer);
152 }
153 fclose(inputFp);
154 extractor->deInitExtractor();
155 delete decoder;
156 delete mEncoder;
Manisha Jajoo2d931a82019-12-20 15:49:52 +0530157 mEncoder = nullptr;
Manisha Jajoo19492a02019-10-14 16:38:17 +0530158}
159
160INSTANTIATE_TEST_SUITE_P(
161 AudioEncoderTest, C2EncoderTest,
Manisha Jajoo2d931a82019-12-20 15:49:52 +0530162 ::testing::Values(make_pair("bbb_44100hz_2ch_128kbps_aac_30sec.mp4", "aac"),
163 make_pair("bbb_8000hz_1ch_8kbps_amrnb_30sec.3gp", "amrnb"),
164 make_pair("bbb_16000hz_1ch_9kbps_amrwb_30sec.3gp", "amrwb"),
165 make_pair("bbb_44100hz_2ch_600kbps_flac_30sec.mp4", "flac"),
166 make_pair("bbb_48000hz_2ch_100kbps_opus_30sec.webm", "opus")));
Manisha Jajoo19492a02019-10-14 16:38:17 +0530167
168INSTANTIATE_TEST_SUITE_P(
169 VideoEncoderTest, C2EncoderTest,
Manisha Jajoo2d931a82019-12-20 15:49:52 +0530170 ::testing::Values(make_pair("crowd_1920x1080_25fps_4000kbps_vp9.webm", "vp9"),
171 make_pair("crowd_1920x1080_25fps_4000kbps_vp8.webm", "vp8"),
172 make_pair("crowd_176x144_25fps_6000kbps_mpeg4.mp4", "mpeg4"),
173 make_pair("crowd_176x144_25fps_6000kbps_h263.3gp", "h263"),
174 make_pair("crowd_1920x1080_25fps_6700kbps_h264.ts", "avc"),
175 make_pair("crowd_1920x1080_25fps_4000kbps_h265.mkv", "hevc")));
Manisha Jajoo19492a02019-10-14 16:38:17 +0530176
177int main(int argc, char **argv) {
178 gEnv = new BenchmarkTestEnvironment();
179 ::testing::AddGlobalTestEnvironment(gEnv);
180 ::testing::InitGoogleTest(&argc, argv);
181 int status = gEnv->initFromOptions(argc, argv);
182 if (status == 0) {
183 status = RUN_ALL_TESTS();
184 ALOGV("C2 Encoder Test result = %d\n", status);
185 }
186 return status;
187}