blob: 83f0a4ac329a37b18fe76dfee042dd66d36323a9 [file] [log] [blame]
Linus Nilsson0da327a2020-01-31 16:22:18 -08001/*
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// Unit Test for MediaTrackTranscoder
18
19// #define LOG_NDEBUG 0
20#define LOG_TAG "MediaTrackTranscoderTests"
21
22#include <android-base/logging.h>
Linus Nilssonc6221db2020-03-18 14:46:22 -070023#include <android/binder_process.h>
Linus Nilsson0da327a2020-01-31 16:22:18 -080024#include <fcntl.h>
25#include <gtest/gtest.h>
26#include <media/MediaSampleReaderNDK.h>
27#include <media/MediaTrackTranscoder.h>
Linus Nilssonc6221db2020-03-18 14:46:22 -070028#include <media/PassthroughTrackTranscoder.h>
Linus Nilsson0da327a2020-01-31 16:22:18 -080029#include <media/VideoTrackTranscoder.h>
30
31#include "TrackTranscoderTestUtils.h"
32
33namespace android {
34
35/** TrackTranscoder types to test. */
36enum TrackTranscoderType {
37 VIDEO,
Linus Nilssonc6221db2020-03-18 14:46:22 -070038 PASSTHROUGH,
Linus Nilsson0da327a2020-01-31 16:22:18 -080039};
40
41class MediaTrackTranscoderTests : public ::testing::TestWithParam<TrackTranscoderType> {
42public:
43 MediaTrackTranscoderTests() { LOG(DEBUG) << "MediaTrackTranscoderTests created"; }
44
45 void SetUp() override {
46 LOG(DEBUG) << "MediaTrackTranscoderTests set up";
47
Linus Nilssonc6221db2020-03-18 14:46:22 -070048 // Need to start a thread pool to prevent AMediaExtractor binder calls from starving
49 // (b/155663561).
50 ABinderProcess_startThreadPool();
51
Linus Nilsson0da327a2020-01-31 16:22:18 -080052 mCallback = std::make_shared<TestCallback>();
53
54 switch (GetParam()) {
55 case VIDEO:
Linus Nilssone4716f22020-07-10 16:07:57 -070056 mTranscoder = VideoTrackTranscoder::create(mCallback);
Linus Nilssonc6221db2020-03-18 14:46:22 -070057 break;
58 case PASSTHROUGH:
59 mTranscoder = std::make_shared<PassthroughTrackTranscoder>(mCallback);
Linus Nilsson0da327a2020-01-31 16:22:18 -080060 break;
61 }
62 ASSERT_NE(mTranscoder, nullptr);
63
64 initSampleReader();
65 }
66
67 void initSampleReader() {
68 const char* sourcePath =
Chong Zhangd6e4aec2020-06-22 14:13:07 -070069 "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
Linus Nilsson0da327a2020-01-31 16:22:18 -080070
71 const int sourceFd = open(sourcePath, O_RDONLY);
72 ASSERT_GT(sourceFd, 0);
73
74 const size_t fileSize = lseek(sourceFd, 0, SEEK_END);
75 lseek(sourceFd, 0, SEEK_SET);
76
77 mMediaSampleReader = MediaSampleReaderNDK::createFromFd(sourceFd, 0 /* offset */, fileSize);
78 ASSERT_NE(mMediaSampleReader, nullptr);
79 close(sourceFd);
80
81 for (size_t trackIndex = 0; trackIndex < mMediaSampleReader->getTrackCount();
82 ++trackIndex) {
83 AMediaFormat* trackFormat = mMediaSampleReader->getTrackFormat(trackIndex);
84 ASSERT_NE(trackFormat, nullptr);
85
86 const char* mime = nullptr;
87 AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime);
88 ASSERT_NE(mime, nullptr);
89
90 if (GetParam() == VIDEO && strncmp(mime, "video/", 6) == 0) {
91 mTrackIndex = trackIndex;
92
Linus Nilsson800793f2020-07-31 16:16:38 -070093 mSourceFormat = std::shared_ptr<AMediaFormat>(trackFormat, &AMediaFormat_delete);
Linus Nilsson0da327a2020-01-31 16:22:18 -080094 ASSERT_NE(mSourceFormat, nullptr);
95
96 mDestinationFormat =
97 TrackTranscoderTestUtils::getDefaultVideoDestinationFormat(trackFormat);
98 ASSERT_NE(mDestinationFormat, nullptr);
99 break;
Linus Nilssonc6221db2020-03-18 14:46:22 -0700100 } else if (GetParam() == PASSTHROUGH && strncmp(mime, "audio/", 6) == 0) {
101 // TODO(lnilsson): Test metadata track passthrough after hkuang@ provides sample.
102 mTrackIndex = trackIndex;
103
Linus Nilsson800793f2020-07-31 16:16:38 -0700104 mSourceFormat = std::shared_ptr<AMediaFormat>(trackFormat, &AMediaFormat_delete);
Linus Nilssonc6221db2020-03-18 14:46:22 -0700105 ASSERT_NE(mSourceFormat, nullptr);
106 break;
Linus Nilsson0da327a2020-01-31 16:22:18 -0800107 }
108
109 AMediaFormat_delete(trackFormat);
110 }
111
112 ASSERT_NE(mSourceFormat, nullptr);
Linus Nilsson6233fed2020-08-13 15:15:14 -0700113 EXPECT_EQ(mMediaSampleReader->selectTrack(mTrackIndex), AMEDIA_OK);
Linus Nilsson0da327a2020-01-31 16:22:18 -0800114 }
115
116 // Drains the transcoder's output queue in a loop.
Linus Nilssonc31d2492020-09-23 12:30:00 -0700117 void drainOutputSamples(int numSamplesToSave = 0) {
118 mTranscoder->setSampleConsumer(
119 [this, numSamplesToSave](const std::shared_ptr<MediaSample>& sample) {
120 ASSERT_NE(sample, nullptr);
121
122 mGotEndOfStream = (sample->info.flags & SAMPLE_FLAG_END_OF_STREAM) != 0;
123
124 if (mSavedSamples.size() < numSamplesToSave) {
125 mSavedSamples.push_back(sample);
126 }
127
128 if (mSavedSamples.size() == numSamplesToSave || mGotEndOfStream) {
129 mSamplesSavedSemaphore.signal();
130 }
131 });
Linus Nilsson0da327a2020-01-31 16:22:18 -0800132 }
133
Linus Nilssonc31d2492020-09-23 12:30:00 -0700134 void TearDown() override { LOG(DEBUG) << "MediaTrackTranscoderTests tear down"; }
Linus Nilsson0da327a2020-01-31 16:22:18 -0800135
136 ~MediaTrackTranscoderTests() { LOG(DEBUG) << "MediaTrackTranscoderTests destroyed"; }
137
138protected:
139 std::shared_ptr<MediaTrackTranscoder> mTranscoder;
140 std::shared_ptr<TestCallback> mCallback;
141
142 std::shared_ptr<MediaSampleReader> mMediaSampleReader;
143 int mTrackIndex;
144
145 std::shared_ptr<AMediaFormat> mSourceFormat;
146 std::shared_ptr<AMediaFormat> mDestinationFormat;
147
Linus Nilssonc31d2492020-09-23 12:30:00 -0700148 std::vector<std::shared_ptr<MediaSample>> mSavedSamples;
149 OneShotSemaphore mSamplesSavedSemaphore;
Linus Nilsson0da327a2020-01-31 16:22:18 -0800150 bool mGotEndOfStream = false;
151};
152
153TEST_P(MediaTrackTranscoderTests, WaitNormalOperation) {
154 LOG(DEBUG) << "Testing WaitNormalOperation";
155 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
156 AMEDIA_OK);
157 ASSERT_TRUE(mTranscoder->start());
Linus Nilssonc31d2492020-09-23 12:30:00 -0700158 drainOutputSamples();
Linus Nilsson0da327a2020-01-31 16:22:18 -0800159 EXPECT_EQ(mCallback->waitUntilFinished(), AMEDIA_OK);
Linus Nilssone4716f22020-07-10 16:07:57 -0700160 EXPECT_TRUE(mTranscoder->stop());
Linus Nilsson0da327a2020-01-31 16:22:18 -0800161 EXPECT_TRUE(mGotEndOfStream);
162}
163
164TEST_P(MediaTrackTranscoderTests, StopNormalOperation) {
165 LOG(DEBUG) << "Testing StopNormalOperation";
166 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
167 AMEDIA_OK);
168 EXPECT_TRUE(mTranscoder->start());
169 EXPECT_TRUE(mTranscoder->stop());
170}
171
172TEST_P(MediaTrackTranscoderTests, StartWithoutConfigure) {
173 LOG(DEBUG) << "Testing StartWithoutConfigure";
174 EXPECT_FALSE(mTranscoder->start());
175}
176
177TEST_P(MediaTrackTranscoderTests, StopWithoutStart) {
178 LOG(DEBUG) << "Testing StopWithoutStart";
179 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
180 AMEDIA_OK);
181 EXPECT_FALSE(mTranscoder->stop());
182}
183
184TEST_P(MediaTrackTranscoderTests, DoubleStartStop) {
185 LOG(DEBUG) << "Testing DoubleStartStop";
186 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
187 AMEDIA_OK);
188 EXPECT_TRUE(mTranscoder->start());
189 EXPECT_FALSE(mTranscoder->start());
190 EXPECT_TRUE(mTranscoder->stop());
191 EXPECT_FALSE(mTranscoder->stop());
192}
193
194TEST_P(MediaTrackTranscoderTests, DoubleConfigure) {
195 LOG(DEBUG) << "Testing DoubleConfigure";
196 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
197 AMEDIA_OK);
198 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
199 AMEDIA_ERROR_UNSUPPORTED);
200}
201
202TEST_P(MediaTrackTranscoderTests, ConfigureAfterFail) {
203 LOG(DEBUG) << "Testing ConfigureAfterFail";
204 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, -1, mDestinationFormat),
205 AMEDIA_ERROR_INVALID_PARAMETER);
206 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
207 AMEDIA_OK);
208}
209
210TEST_P(MediaTrackTranscoderTests, RestartAfterStop) {
211 LOG(DEBUG) << "Testing RestartAfterStop";
212 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
213 AMEDIA_OK);
214 EXPECT_TRUE(mTranscoder->start());
215 EXPECT_TRUE(mTranscoder->stop());
216 EXPECT_FALSE(mTranscoder->start());
217}
218
219TEST_P(MediaTrackTranscoderTests, RestartAfterFinish) {
220 LOG(DEBUG) << "Testing RestartAfterFinish";
221 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
222 AMEDIA_OK);
223 ASSERT_TRUE(mTranscoder->start());
Linus Nilssonc31d2492020-09-23 12:30:00 -0700224 drainOutputSamples();
Linus Nilsson0da327a2020-01-31 16:22:18 -0800225 EXPECT_EQ(mCallback->waitUntilFinished(), AMEDIA_OK);
226 EXPECT_TRUE(mTranscoder->stop());
227 EXPECT_FALSE(mTranscoder->start());
Linus Nilsson0da327a2020-01-31 16:22:18 -0800228 EXPECT_TRUE(mGotEndOfStream);
229}
230
Linus Nilssonc6221db2020-03-18 14:46:22 -0700231TEST_P(MediaTrackTranscoderTests, HoldSampleAfterTranscoderRelease) {
232 LOG(DEBUG) << "Testing HoldSampleAfterTranscoderRelease";
233 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
234 AMEDIA_OK);
235 ASSERT_TRUE(mTranscoder->start());
Linus Nilssonc31d2492020-09-23 12:30:00 -0700236 drainOutputSamples(1 /* numSamplesToSave */);
Linus Nilssonc6221db2020-03-18 14:46:22 -0700237 EXPECT_EQ(mCallback->waitUntilFinished(), AMEDIA_OK);
Linus Nilssone4716f22020-07-10 16:07:57 -0700238 EXPECT_TRUE(mTranscoder->stop());
Linus Nilssonc6221db2020-03-18 14:46:22 -0700239 EXPECT_TRUE(mGotEndOfStream);
240
241 mTranscoder.reset();
Linus Nilssonc31d2492020-09-23 12:30:00 -0700242
Linus Nilssonc6221db2020-03-18 14:46:22 -0700243 std::this_thread::sleep_for(std::chrono::milliseconds(20));
Linus Nilssonc31d2492020-09-23 12:30:00 -0700244 mSavedSamples.clear();
Linus Nilssonc6221db2020-03-18 14:46:22 -0700245}
246
247TEST_P(MediaTrackTranscoderTests, HoldSampleAfterTranscoderStop) {
248 LOG(DEBUG) << "Testing HoldSampleAfterTranscoderStop";
249 EXPECT_EQ(mTranscoder->configure(mMediaSampleReader, mTrackIndex, mDestinationFormat),
250 AMEDIA_OK);
251 ASSERT_TRUE(mTranscoder->start());
Linus Nilssonc31d2492020-09-23 12:30:00 -0700252 drainOutputSamples(1 /* numSamplesToSave */);
253 mSamplesSavedSemaphore.wait();
Linus Nilssonc6221db2020-03-18 14:46:22 -0700254 EXPECT_TRUE(mTranscoder->stop());
255
256 std::this_thread::sleep_for(std::chrono::milliseconds(20));
Linus Nilssonc31d2492020-09-23 12:30:00 -0700257 mSavedSamples.clear();
Linus Nilssonc6221db2020-03-18 14:46:22 -0700258}
259
Linus Nilsson0da327a2020-01-31 16:22:18 -0800260TEST_P(MediaTrackTranscoderTests, NullSampleReader) {
261 LOG(DEBUG) << "Testing NullSampleReader";
262 std::shared_ptr<MediaSampleReader> nullSampleReader;
263 EXPECT_NE(mTranscoder->configure(nullSampleReader, mTrackIndex, mDestinationFormat), AMEDIA_OK);
Linus Nilssonc6221db2020-03-18 14:46:22 -0700264 ASSERT_FALSE(mTranscoder->start());
Linus Nilsson0da327a2020-01-31 16:22:18 -0800265}
266
267TEST_P(MediaTrackTranscoderTests, InvalidTrackIndex) {
268 LOG(DEBUG) << "Testing InvalidTrackIndex";
269 EXPECT_NE(mTranscoder->configure(mMediaSampleReader, -1, mDestinationFormat), AMEDIA_OK);
270 EXPECT_NE(mTranscoder->configure(mMediaSampleReader, mMediaSampleReader->getTrackCount(),
271 mDestinationFormat),
272 AMEDIA_OK);
273}
274
275}; // namespace android
276
277using namespace android;
278
279INSTANTIATE_TEST_SUITE_P(MediaTrackTranscoderTestsAll, MediaTrackTranscoderTests,
Linus Nilssonc6221db2020-03-18 14:46:22 -0700280 ::testing::Values(VIDEO, PASSTHROUGH));
Linus Nilsson0da327a2020-01-31 16:22:18 -0800281
282int main(int argc, char** argv) {
283 ::testing::InitGoogleTest(&argc, argv);
284 return RUN_ALL_TESTS();
285}