Manisha Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 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 "C2EncoderTest" |
| 19 | |
Manisha Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 20 | #include <fstream> |
| 21 | #include <iostream> |
| 22 | #include <limits> |
| 23 | |
| 24 | #include "BenchmarkTestEnvironment.h" |
| 25 | #include "C2Encoder.h" |
| 26 | #include "Decoder.h" |
| 27 | |
| 28 | static BenchmarkTestEnvironment *gEnv = nullptr; |
| 29 | |
| 30 | class C2EncoderTest : public ::testing::TestWithParam<pair<string, string>> { |
| 31 | public: |
Manisha Jajoo | 2d931a8 | 2019-12-20 15:49:52 +0530 | [diff] [blame] | 32 | 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 Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 45 | |
| 46 | void setupC2EncoderTest(); |
| 47 | |
| 48 | vector<string> mCodecList; |
| 49 | C2Encoder *mEncoder; |
| 50 | }; |
| 51 | |
| 52 | void 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 | |
| 63 | TEST_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 Jajoo | 2d931a8 | 2019-12-20 15:49:52 +0530 | [diff] [blame] | 142 | ALOGV("codec : %s", codecName.c_str()); |
Manisha Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 143 | 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 Jajoo | 2d931a8 | 2019-12-20 15:49:52 +0530 | [diff] [blame] | 157 | mEncoder = nullptr; |
Manisha Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 158 | } |
| 159 | |
| 160 | INSTANTIATE_TEST_SUITE_P( |
| 161 | AudioEncoderTest, C2EncoderTest, |
Manisha Jajoo | 2d931a8 | 2019-12-20 15:49:52 +0530 | [diff] [blame] | 162 | ::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 Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 167 | |
| 168 | INSTANTIATE_TEST_SUITE_P( |
| 169 | VideoEncoderTest, C2EncoderTest, |
Manisha Jajoo | 2d931a8 | 2019-12-20 15:49:52 +0530 | [diff] [blame] | 170 | ::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 Jajoo | 19492a0 | 2019-10-14 16:38:17 +0530 | [diff] [blame] | 176 | |
| 177 | int 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 | } |