blob: 4e33ec3b72a6725fbba575db4f80a1133d433eb6 [file] [log] [blame]
Linus Nilssoncab39d82020-05-14 16:32:21 -07001/*
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 MediaTranscoder
18
19// #define LOG_NDEBUG 0
20#define LOG_TAG "MediaTranscoderTests"
21
22#include <android-base/logging.h>
Linus Nilsson93cf9132020-09-24 12:12:48 -070023#include <android/binder_process.h>
Chong Zhangb55c5452020-06-26 14:32:12 -070024#include <fcntl.h>
Linus Nilssoncab39d82020-05-14 16:32:21 -070025#include <gtest/gtest.h>
Chong Zhang5855ee52020-06-22 11:41:25 -070026#include <media/MediaSampleReaderNDK.h>
Linus Nilssoncab39d82020-05-14 16:32:21 -070027#include <media/MediaTranscoder.h>
Chong Zhang5855ee52020-06-22 11:41:25 -070028#include <media/NdkCommon.h>
Linus Nilssoncab39d82020-05-14 16:32:21 -070029
30namespace android {
31
Chong Zhang5855ee52020-06-22 11:41:25 -070032#define DEFINE_FORMAT_VALUE_EQUAL_FUNC(_type, _typeName) \
33 static bool equal##_typeName(const char* key, AMediaFormat* src, AMediaFormat* dst) { \
34 _type srcVal, dstVal; \
35 bool srcPresent = AMediaFormat_get##_typeName(src, key, &srcVal); \
36 bool dstPresent = AMediaFormat_get##_typeName(dst, key, &dstVal); \
37 return (srcPresent == dstPresent) && (!srcPresent || (srcVal == dstVal)); \
38 }
39
40DEFINE_FORMAT_VALUE_EQUAL_FUNC(int64_t, Int64);
41DEFINE_FORMAT_VALUE_EQUAL_FUNC(int32_t, Int32);
42
43struct FormatVerifierEntry {
44 const char* key;
Chong Zhangd6e4aec2020-06-22 14:13:07 -070045 std::function<bool(const char*, AMediaFormat*, AMediaFormat*)> equal;
Chong Zhang5855ee52020-06-22 11:41:25 -070046};
47
48static const FormatVerifierEntry kFieldsToPreserve[] = {
49 {AMEDIAFORMAT_KEY_DURATION, equalInt64}, {AMEDIAFORMAT_KEY_WIDTH, equalInt32},
50 {AMEDIAFORMAT_KEY_HEIGHT, equalInt32}, {AMEDIAFORMAT_KEY_FRAME_RATE, equalInt32},
51 {AMEDIAFORMAT_KEY_FRAME_COUNT, equalInt32}, {AMEDIAFORMAT_KEY_DISPLAY_WIDTH, equalInt32},
52 {AMEDIAFORMAT_KEY_DISPLAY_HEIGHT, equalInt32}, {AMEDIAFORMAT_KEY_SAR_WIDTH, equalInt32},
53 {AMEDIAFORMAT_KEY_SAR_HEIGHT, equalInt32}, {AMEDIAFORMAT_KEY_ROTATION, equalInt32},
54};
55
Linus Nilssoncab39d82020-05-14 16:32:21 -070056class TestCallbacks : public MediaTranscoder::CallbackInterface {
57public:
58 virtual void onFinished(const MediaTranscoder* transcoder __unused) override {
59 std::unique_lock<std::mutex> lock(mMutex);
60 EXPECT_FALSE(mFinished);
61 mFinished = true;
62 mCondition.notify_all();
63 }
64
65 virtual void onError(const MediaTranscoder* transcoder __unused,
66 media_status_t error) override {
67 std::unique_lock<std::mutex> lock(mMutex);
68 EXPECT_NE(error, AMEDIA_OK);
69 EXPECT_FALSE(mFinished);
70 mFinished = true;
71 mStatus = error;
72 mCondition.notify_all();
73 }
74
75 virtual void onProgressUpdate(const MediaTranscoder* transcoder __unused,
Linus Nilsson93cf9132020-09-24 12:12:48 -070076 int32_t progress) override {
77 std::unique_lock<std::mutex> lock(mMutex);
78 if (progress > 0 && !mProgressMade) {
79 mProgressMade = true;
80 mCondition.notify_all();
81 }
82 }
Linus Nilssoncab39d82020-05-14 16:32:21 -070083
Chong Zhang457c6892021-02-01 15:34:20 -080084 virtual void onHeartBeat(const MediaTranscoder* transcoder __unused) override {
85 std::unique_lock<std::mutex> lock(mMutex);
86 mHeartBeatCount++;
87 }
88
Linus Nilssoncab39d82020-05-14 16:32:21 -070089 virtual void onCodecResourceLost(const MediaTranscoder* transcoder __unused,
Chong Zhange4e088f2020-10-21 19:10:42 -070090 const std::shared_ptr<ndk::ScopedAParcel>& pausedState
Linus Nilssoncab39d82020-05-14 16:32:21 -070091 __unused) override {}
92
93 void waitForTranscodingFinished() {
94 std::unique_lock<std::mutex> lock(mMutex);
95 while (!mFinished) {
96 mCondition.wait(lock);
97 }
98 }
99
Linus Nilsson93cf9132020-09-24 12:12:48 -0700100 void waitForProgressMade() {
101 std::unique_lock<std::mutex> lock(mMutex);
102 while (!mProgressMade && !mFinished) {
103 mCondition.wait(lock);
104 }
105 }
Linus Nilssoncab39d82020-05-14 16:32:21 -0700106 media_status_t mStatus = AMEDIA_OK;
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700107 bool mFinished = false;
Chong Zhang457c6892021-02-01 15:34:20 -0800108 int32_t mHeartBeatCount = 0;
Linus Nilssoncab39d82020-05-14 16:32:21 -0700109
110private:
111 std::mutex mMutex;
112 std::condition_variable mCondition;
Linus Nilsson93cf9132020-09-24 12:12:48 -0700113 bool mProgressMade = false;
Linus Nilssoncab39d82020-05-14 16:32:21 -0700114};
115
Chong Zhang308e91f2020-06-10 15:27:56 -0700116// Write-only, create file if non-existent, don't overwrite existing file.
117static constexpr int kOpenFlags = O_WRONLY | O_CREAT | O_EXCL;
118// User R+W permission.
119static constexpr int kFileMode = S_IRUSR | S_IWUSR;
Linus Nilssoncab39d82020-05-14 16:32:21 -0700120
121class MediaTranscoderTests : public ::testing::Test {
122public:
123 MediaTranscoderTests() { LOG(DEBUG) << "MediaTranscoderTests created"; }
124 ~MediaTranscoderTests() { LOG(DEBUG) << "MediaTranscoderTests destroyed"; }
125
126 void SetUp() override {
127 LOG(DEBUG) << "MediaTranscoderTests set up";
128 mCallbacks = std::make_shared<TestCallbacks>();
Linus Nilsson93cf9132020-09-24 12:12:48 -0700129 ABinderProcess_startThreadPool();
Linus Nilssoncab39d82020-05-14 16:32:21 -0700130 }
131
132 void TearDown() override {
133 LOG(DEBUG) << "MediaTranscoderTests tear down";
134 mCallbacks.reset();
135 }
136
137 void deleteFile(const char* path) { unlink(path); }
138
Linus Nilsson800793f2020-07-31 16:16:38 -0700139 float getFileSizeDiffPercent(const char* path1, const char* path2, bool absolute = false) {
140 struct stat s1, s2;
141 EXPECT_EQ(stat(path1, &s1), 0);
142 EXPECT_EQ(stat(path2, &s2), 0);
143
144 int64_t diff = s2.st_size - s1.st_size;
145 if (absolute && diff < 0) diff = -diff;
146
147 return (float)diff * 100.0f / s1.st_size;
148 }
149
Linus Nilsson93cf9132020-09-24 12:12:48 -0700150 typedef enum {
151 kRunToCompletion,
Chong Zhang457c6892021-02-01 15:34:20 -0800152 kCheckHeartBeat,
Linus Nilsson93cf9132020-09-24 12:12:48 -0700153 kCancelAfterProgress,
154 kCancelAfterStart,
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700155 kPauseAfterProgress,
156 kPauseAfterStart,
Linus Nilsson93cf9132020-09-24 12:12:48 -0700157 } TranscodeExecutionControl;
158
Linus Nilssoncab39d82020-05-14 16:32:21 -0700159 using FormatConfigurationCallback = std::function<AMediaFormat*(AMediaFormat*)>;
Chong Zhang5855ee52020-06-22 11:41:25 -0700160 media_status_t transcodeHelper(const char* srcPath, const char* destPath,
Linus Nilsson93cf9132020-09-24 12:12:48 -0700161 FormatConfigurationCallback formatCallback,
Chong Zhang457c6892021-02-01 15:34:20 -0800162 TranscodeExecutionControl executionControl = kRunToCompletion,
163 int64_t heartBeatIntervalUs = -1) {
164 auto transcoder = MediaTranscoder::create(mCallbacks, heartBeatIntervalUs);
Linus Nilssoncab39d82020-05-14 16:32:21 -0700165 EXPECT_NE(transcoder, nullptr);
166
Chong Zhang5855ee52020-06-22 11:41:25 -0700167 const int srcFd = open(srcPath, O_RDONLY);
Chong Zhang308e91f2020-06-10 15:27:56 -0700168 EXPECT_EQ(transcoder->configureSource(srcFd), AMEDIA_OK);
Linus Nilssoncab39d82020-05-14 16:32:21 -0700169
170 std::vector<std::shared_ptr<AMediaFormat>> trackFormats = transcoder->getTrackFormats();
171 EXPECT_GT(trackFormats.size(), 0);
172
173 for (int i = 0; i < trackFormats.size(); ++i) {
174 AMediaFormat* format = formatCallback(trackFormats[i].get());
175 EXPECT_EQ(transcoder->configureTrackFormat(i, format), AMEDIA_OK);
Chong Zhang5855ee52020-06-22 11:41:25 -0700176
177 // Save original video track format for verification.
178 const char* mime = nullptr;
179 AMediaFormat_getString(trackFormats[i].get(), AMEDIAFORMAT_KEY_MIME, &mime);
180 if (strncmp(mime, "video/", 6) == 0) {
181 mSourceVideoFormat = trackFormats[i];
182 }
183
Linus Nilssoncab39d82020-05-14 16:32:21 -0700184 if (format != nullptr) {
185 AMediaFormat_delete(format);
186 }
187 }
188 deleteFile(destPath);
Chong Zhang308e91f2020-06-10 15:27:56 -0700189 const int dstFd = open(destPath, kOpenFlags, kFileMode);
190 EXPECT_EQ(transcoder->configureDestination(dstFd), AMEDIA_OK);
Linus Nilssoncab39d82020-05-14 16:32:21 -0700191
192 media_status_t startStatus = transcoder->start();
193 EXPECT_EQ(startStatus, AMEDIA_OK);
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700194
Linus Nilssoncab39d82020-05-14 16:32:21 -0700195 if (startStatus == AMEDIA_OK) {
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700196 std::shared_ptr<ndk::ScopedAParcel> pausedState;
197
Linus Nilsson93cf9132020-09-24 12:12:48 -0700198 switch (executionControl) {
199 case kCancelAfterProgress:
200 mCallbacks->waitForProgressMade();
201 FALLTHROUGH_INTENDED;
202 case kCancelAfterStart:
203 transcoder->cancel();
204 break;
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700205 case kPauseAfterProgress:
206 mCallbacks->waitForProgressMade();
207 FALLTHROUGH_INTENDED;
208 case kPauseAfterStart:
209 transcoder->pause(&pausedState);
210 break;
Chong Zhang457c6892021-02-01 15:34:20 -0800211 case kCheckHeartBeat: {
212 mCallbacks->waitForProgressMade();
213 auto startTime = std::chrono::system_clock::now();
214 mCallbacks->waitForTranscodingFinished();
215 auto finishTime = std::chrono::system_clock::now();
216 int32_t expectedCount =
217 (finishTime - startTime) / std::chrono::microseconds(heartBeatIntervalUs);
218 // Here we relax the expected count by 1, in case the last heart-beat just
219 // missed the window, other than that the count should be exact.
220 EXPECT_GE(mCallbacks->mHeartBeatCount, expectedCount - 1);
221 break;
222 }
Linus Nilsson93cf9132020-09-24 12:12:48 -0700223 case kRunToCompletion:
224 default:
225 mCallbacks->waitForTranscodingFinished();
226 break;
227 }
Linus Nilssoncab39d82020-05-14 16:32:21 -0700228 }
Chong Zhang308e91f2020-06-10 15:27:56 -0700229 close(srcFd);
230 close(dstFd);
Linus Nilssoncab39d82020-05-14 16:32:21 -0700231
232 return mCallbacks->mStatus;
233 }
234
Linus Nilsson800793f2020-07-31 16:16:38 -0700235 void testTranscodeVideo(const char* srcPath, const char* destPath, const char* dstMime,
236 int32_t bitrate = 0) {
237 EXPECT_EQ(transcodeHelper(srcPath, destPath,
238 [dstMime, bitrate](AMediaFormat* sourceFormat) {
239 AMediaFormat* format = nullptr;
240 const char* mime = nullptr;
241 AMediaFormat_getString(sourceFormat, AMEDIAFORMAT_KEY_MIME,
242 &mime);
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700243
Linus Nilsson800793f2020-07-31 16:16:38 -0700244 if (strncmp(mime, "video/", 6) == 0 &&
245 (bitrate > 0 || dstMime != nullptr)) {
246 format = AMediaFormat_new();
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700247
Linus Nilsson800793f2020-07-31 16:16:38 -0700248 if (bitrate > 0) {
249 AMediaFormat_setInt32(
250 format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
251 }
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700252
Linus Nilsson800793f2020-07-31 16:16:38 -0700253 if (dstMime != nullptr) {
254 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME,
255 dstMime);
256 }
257 }
258 return format;
259 }),
260 AMEDIA_OK);
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700261
262 if (dstMime != nullptr) {
263 std::vector<FormatVerifierEntry> extraVerifiers = {
264 {AMEDIAFORMAT_KEY_MIME,
265 [dstMime](const char* key, AMediaFormat* src __unused, AMediaFormat* dst) {
266 const char* mime = nullptr;
267 AMediaFormat_getString(dst, key, &mime);
268 return !strcmp(mime, dstMime);
269 }},
270 };
271 verifyOutputFormat(destPath, &extraVerifiers);
272 } else {
273 verifyOutputFormat(destPath);
274 }
275 }
276
Chong Zhang5855ee52020-06-22 11:41:25 -0700277 void verifyOutputFormat(const char* destPath,
278 const std::vector<FormatVerifierEntry>* extraVerifiers = nullptr) {
279 int dstFd = open(destPath, O_RDONLY);
280 EXPECT_GT(dstFd, 0);
281 ssize_t fileSize = lseek(dstFd, 0, SEEK_END);
282 lseek(dstFd, 0, SEEK_SET);
283
284 std::shared_ptr<MediaSampleReader> sampleReader =
285 MediaSampleReaderNDK::createFromFd(dstFd, 0, fileSize);
Linus Nilsson42a971b2020-07-01 16:41:11 -0700286 ASSERT_NE(sampleReader, nullptr);
Chong Zhang5855ee52020-06-22 11:41:25 -0700287
288 std::shared_ptr<AMediaFormat> videoFormat;
289 const size_t trackCount = sampleReader->getTrackCount();
290 for (size_t trackIndex = 0; trackIndex < trackCount; ++trackIndex) {
291 AMediaFormat* trackFormat = sampleReader->getTrackFormat(static_cast<int>(trackIndex));
292 if (trackFormat != nullptr) {
293 const char* mime = nullptr;
294 AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime);
Linus Nilsson42a971b2020-07-01 16:41:11 -0700295
Chong Zhang5855ee52020-06-22 11:41:25 -0700296 if (strncmp(mime, "video/", 6) == 0) {
297 LOG(INFO) << "Track # " << trackIndex << ": "
298 << AMediaFormat_toString(trackFormat);
299 videoFormat = std::shared_ptr<AMediaFormat>(trackFormat, &AMediaFormat_delete);
300 break;
301 }
302 }
303 }
304
305 EXPECT_NE(videoFormat, nullptr);
Linus Nilssonaf4a3212020-12-15 08:18:25 -0800306 if (videoFormat != nullptr) {
307 LOG(INFO) << "source video format: " << AMediaFormat_toString(mSourceVideoFormat.get());
308 LOG(INFO) << "transcoded video format: " << AMediaFormat_toString(videoFormat.get());
Chong Zhang5855ee52020-06-22 11:41:25 -0700309
Linus Nilssonaf4a3212020-12-15 08:18:25 -0800310 for (int i = 0; i < (sizeof(kFieldsToPreserve) / sizeof(kFieldsToPreserve[0])); ++i) {
311 EXPECT_TRUE(kFieldsToPreserve[i].equal(kFieldsToPreserve[i].key,
312 mSourceVideoFormat.get(), videoFormat.get()))
313 << "Failed at key " << kFieldsToPreserve[i].key;
314 }
Chong Zhang5855ee52020-06-22 11:41:25 -0700315
Linus Nilssonaf4a3212020-12-15 08:18:25 -0800316 if (extraVerifiers != nullptr) {
317 for (int i = 0; i < extraVerifiers->size(); ++i) {
318 const FormatVerifierEntry& entry = (*extraVerifiers)[i];
319 EXPECT_TRUE(
320 entry.equal(entry.key, mSourceVideoFormat.get(), videoFormat.get()));
321 }
Chong Zhang5855ee52020-06-22 11:41:25 -0700322 }
323 }
324
325 close(dstFd);
326 }
327
Linus Nilssoncab39d82020-05-14 16:32:21 -0700328 std::shared_ptr<TestCallbacks> mCallbacks;
Chong Zhang5855ee52020-06-22 11:41:25 -0700329 std::shared_ptr<AMediaFormat> mSourceVideoFormat;
Linus Nilssoncab39d82020-05-14 16:32:21 -0700330};
331
332TEST_F(MediaTranscoderTests, TestPassthrough) {
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700333 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
Linus Nilssoncab39d82020-05-14 16:32:21 -0700334 const char* destPath = "/data/local/tmp/MediaTranscoder_Passthrough.MP4";
Linus Nilsson800793f2020-07-31 16:16:38 -0700335 testTranscodeVideo(srcPath, destPath, nullptr);
Linus Nilssoncab39d82020-05-14 16:32:21 -0700336}
337
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700338TEST_F(MediaTranscoderTests, TestVideoTranscode_AvcToAvc_Basic) {
339 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
340 const char* destPath = "/data/local/tmp/MediaTranscoder_VideoTranscode_AvcToAvc_Basic.MP4";
Linus Nilsson800793f2020-07-31 16:16:38 -0700341 testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
Chong Zhang5855ee52020-06-22 11:41:25 -0700342}
343
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700344TEST_F(MediaTranscoderTests, TestVideoTranscode_HevcToAvc_Basic) {
345 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/jets_hevc_1280x720_20Mbps.mp4";
346 const char* destPath = "/data/local/tmp/MediaTranscoder_VideoTranscode_HevcToAvc_Basic.MP4";
347 testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
348}
Chong Zhang5855ee52020-06-22 11:41:25 -0700349
Chong Zhangd6e4aec2020-06-22 14:13:07 -0700350TEST_F(MediaTranscoderTests, TestVideoTranscode_HevcToAvc_Rotation) {
351 const char* srcPath =
352 "/data/local/tmp/TranscodingTestAssets/desk_hevc_1920x1080_aac_48KHz_rot90.mp4";
353 const char* destPath = "/data/local/tmp/MediaTranscoder_VideoTranscode_HevcToAvc_Rotation.MP4";
354 testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
Linus Nilssoncab39d82020-05-14 16:32:21 -0700355}
356
Linus Nilsson91ea1f42020-12-16 11:35:27 -0800357TEST_F(MediaTranscoderTests, TestVideoTranscode_4K) {
358#if defined(__i386__) || defined(__x86_64__)
359 LOG(WARNING) << "Skipping 4K test on x86 as SW encoder does not support 4K.";
360 return;
361#else
362 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/Video_4K_HEVC_10Frames_Audio.mp4";
363 const char* destPath = "/data/local/tmp/MediaTranscoder_4K.MP4";
364 testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
365#endif
366}
367
Linus Nilsson800793f2020-07-31 16:16:38 -0700368TEST_F(MediaTranscoderTests, TestPreserveBitrate) {
369 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
370 const char* destPath = "/data/local/tmp/MediaTranscoder_PreserveBitrate.MP4";
371 testTranscodeVideo(srcPath, destPath, AMEDIA_MIMETYPE_VIDEO_AVC);
372
Linus Nilsson24ba9212020-12-02 11:46:39 -0800373 // Require maximum of 25% difference in file size.
374 // TODO(b/174678336): Find a better test asset to tighten the threshold.
375 EXPECT_LT(getFileSizeDiffPercent(srcPath, destPath, true /* absolute*/), 25);
Linus Nilsson800793f2020-07-31 16:16:38 -0700376}
377
378TEST_F(MediaTranscoderTests, TestCustomBitrate) {
379 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/cubicle_avc_480x240_aac_24KHz.mp4";
380 const char* destPath1 = "/data/local/tmp/MediaTranscoder_CustomBitrate_2Mbps.MP4";
381 const char* destPath2 = "/data/local/tmp/MediaTranscoder_CustomBitrate_8Mbps.MP4";
382 testTranscodeVideo(srcPath, destPath1, AMEDIA_MIMETYPE_VIDEO_AVC, 2 * 1000 * 1000);
383 mCallbacks = std::make_shared<TestCallbacks>();
384 testTranscodeVideo(srcPath, destPath2, AMEDIA_MIMETYPE_VIDEO_AVC, 8 * 1000 * 1000);
385
386 // The source asset is very short and heavily compressed from the beginning so don't expect the
Linus Nilsson24ba9212020-12-02 11:46:39 -0800387 // requested bitrate to be exactly matched. However the 8mbps should at least be larger.
388 // TODO(b/174678336): Find a better test asset to tighten the threshold.
389 EXPECT_GT(getFileSizeDiffPercent(destPath1, destPath2), 10);
Linus Nilsson800793f2020-07-31 16:16:38 -0700390}
391
Linus Nilsson93cf9132020-09-24 12:12:48 -0700392static AMediaFormat* getAVCVideoFormat(AMediaFormat* sourceFormat) {
393 AMediaFormat* format = nullptr;
394 const char* mime = nullptr;
395 AMediaFormat_getString(sourceFormat, AMEDIAFORMAT_KEY_MIME, &mime);
396
397 if (strncmp(mime, "video/", 6) == 0) {
398 format = AMediaFormat_new();
399 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
400 }
401
402 return format;
403}
404
405TEST_F(MediaTranscoderTests, TestCancelAfterProgress) {
406 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/longtest_15s.mp4";
407 const char* destPath = "/data/local/tmp/MediaTranscoder_Cancel.MP4";
408
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700409 for (int i = 0; i < 20; ++i) {
Linus Nilsson93cf9132020-09-24 12:12:48 -0700410 EXPECT_EQ(transcodeHelper(srcPath, destPath, getAVCVideoFormat, kCancelAfterProgress),
411 AMEDIA_OK);
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700412 EXPECT_FALSE(mCallbacks->mFinished);
Linus Nilsson93cf9132020-09-24 12:12:48 -0700413 mCallbacks = std::make_shared<TestCallbacks>();
414 }
415}
416
417TEST_F(MediaTranscoderTests, TestCancelAfterStart) {
418 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/longtest_15s.mp4";
419 const char* destPath = "/data/local/tmp/MediaTranscoder_Cancel.MP4";
420
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700421 for (int i = 0; i < 20; ++i) {
Linus Nilsson93cf9132020-09-24 12:12:48 -0700422 EXPECT_EQ(transcodeHelper(srcPath, destPath, getAVCVideoFormat, kCancelAfterStart),
423 AMEDIA_OK);
Linus Nilssonfdb3e332020-09-18 17:11:41 -0700424 EXPECT_FALSE(mCallbacks->mFinished);
425 mCallbacks = std::make_shared<TestCallbacks>();
426 }
427}
428
429TEST_F(MediaTranscoderTests, TestPauseAfterProgress) {
430 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/longtest_15s.mp4";
431 const char* destPath = "/data/local/tmp/MediaTranscoder_Pause.MP4";
432
433 for (int i = 0; i < 20; ++i) {
434 EXPECT_EQ(transcodeHelper(srcPath, destPath, getAVCVideoFormat, kPauseAfterProgress),
435 AMEDIA_OK);
436 EXPECT_FALSE(mCallbacks->mFinished);
437 mCallbacks = std::make_shared<TestCallbacks>();
438 }
439}
440
441TEST_F(MediaTranscoderTests, TestPauseAfterStart) {
442 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/longtest_15s.mp4";
443 const char* destPath = "/data/local/tmp/MediaTranscoder_Pause.MP4";
444
445 for (int i = 0; i < 20; ++i) {
446 EXPECT_EQ(transcodeHelper(srcPath, destPath, getAVCVideoFormat, kPauseAfterStart),
447 AMEDIA_OK);
448 EXPECT_FALSE(mCallbacks->mFinished);
Linus Nilsson93cf9132020-09-24 12:12:48 -0700449 mCallbacks = std::make_shared<TestCallbacks>();
450 }
451}
452
Chong Zhang457c6892021-02-01 15:34:20 -0800453TEST_F(MediaTranscoderTests, TestHeartBeat) {
454 const char* srcPath = "/data/local/tmp/TranscodingTestAssets/longtest_15s.mp4";
455 const char* destPath = "/data/local/tmp/MediaTranscoder_HeartBeat.MP4";
456
457 // Use a shorter value of 500ms than the default 1000ms to get more heart beat for testing.
458 const int64_t heartBeatIntervalUs = 500000LL;
459 EXPECT_EQ(transcodeHelper(srcPath, destPath, getAVCVideoFormat, kCheckHeartBeat,
460 heartBeatIntervalUs),
461 AMEDIA_OK);
462 EXPECT_TRUE(mCallbacks->mFinished);
463}
464
Linus Nilssoncab39d82020-05-14 16:32:21 -0700465} // namespace android
466
467int main(int argc, char** argv) {
468 ::testing::InitGoogleTest(&argc, argv);
469 return RUN_ALL_TESTS();
470}