blob: 8f8ad4ecb95f5de1ecaf5e631b754cf63483e055 [file] [log] [blame]
Linus Nilsson8f0b8762020-07-23 17:12:45 -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/**
18 * Native media transcoder library benchmark tests.
19 *
20 * How to run the benchmark:
21 *
22 * 1. Download the media assets from http://go/transcodingbenchmark and push the directory
23 * ("TranscodingBenchmark") to /data/local/tmp.
24 *
25 * 2. Compile the benchmark and sync to device:
26 * $ mm -j72 && adb sync
27 *
28 * 3. Run:
29 * $ adb shell /data/nativetest64/MediaTranscoderBenchmark/MediaTranscoderBenchmark
30 */
31
32#include <benchmark/benchmark.h>
Naveen Kumar Ponnusamy2d074ba2020-12-17 17:13:45 -080033#include <binder/ProcessState.h>
Linus Nilsson8f0b8762020-07-23 17:12:45 -070034#include <fcntl.h>
35#include <media/MediaTranscoder.h>
Linus Nilsson4aef0de2021-01-29 17:58:55 -080036#include <media/NdkCommon.h>
Linus Nilsson47352412020-12-16 12:21:26 -080037
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +053038#include <iostream>
Linus Nilsson8f0b8762020-07-23 17:12:45 -070039
40using namespace android;
41
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +053042const std::string PARAM_VIDEO_FRAME_RATE = "VideoFrameRate";
43
Linus Nilsson8f0b8762020-07-23 17:12:45 -070044class TranscoderCallbacks : public MediaTranscoder::CallbackInterface {
45public:
46 virtual void onFinished(const MediaTranscoder* transcoder __unused) override {
47 std::unique_lock<std::mutex> lock(mMutex);
48 mFinished = true;
49 mCondition.notify_all();
50 }
51
52 virtual void onError(const MediaTranscoder* transcoder __unused,
53 media_status_t error) override {
54 std::unique_lock<std::mutex> lock(mMutex);
55 mFinished = true;
56 mStatus = error;
57 mCondition.notify_all();
58 }
59
60 virtual void onProgressUpdate(const MediaTranscoder* transcoder __unused,
61 int32_t progress __unused) override {}
62
Chong Zhang457c6892021-02-01 15:34:20 -080063 virtual void onHeartBeat(const MediaTranscoder* transcoder __unused) override {}
64
Linus Nilsson8f0b8762020-07-23 17:12:45 -070065 virtual void onCodecResourceLost(const MediaTranscoder* transcoder __unused,
Chong Zhange4e088f2020-10-21 19:10:42 -070066 const std::shared_ptr<ndk::ScopedAParcel>& pausedState
Linus Nilsson8f0b8762020-07-23 17:12:45 -070067 __unused) override {}
68
69 bool waitForTranscodingFinished() {
70 std::unique_lock<std::mutex> lock(mMutex);
71 while (!mFinished) {
72 if (mCondition.wait_for(lock, std::chrono::minutes(5)) == std::cv_status::timeout) {
73 return false;
74 }
75 }
76 return true;
77 }
78
79 media_status_t mStatus = AMEDIA_OK;
80
81private:
82 std::mutex mMutex;
83 std::condition_variable mCondition;
84 bool mFinished = false;
85};
86
Linus Nilsson16d772b2020-09-29 19:21:11 -070087static AMediaFormat* CreateDefaultVideoFormat() {
Linus Nilsson8f0b8762020-07-23 17:12:45 -070088 // Default bitrate
89 static constexpr int32_t kVideoBitRate = 20 * 1000 * 1000; // 20Mbs
Linus Nilsson16d772b2020-09-29 19:21:11 -070090
91 AMediaFormat* videoFormat = AMediaFormat_new();
92 AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate);
Linus Nilsson4aef0de2021-01-29 17:58:55 -080093 AMediaFormat_setString(videoFormat, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
Linus Nilsson16d772b2020-09-29 19:21:11 -070094 return videoFormat;
95}
96
97/**
98 * Callback to configure tracks for transcoding.
99 * @param mime The source track mime type.
100 * @param dstFormat The destination format if the track should be transcoded or nullptr if the track
101 * should be passed through.
102 * @return True if the track should be included in the output file.
103 */
104using TrackSelectionCallback = std::function<bool(const char* mime, AMediaFormat** dstFormat)>;
105
106static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName,
107 const std::string& dstFileName,
108 TrackSelectionCallback trackSelectionCallback) {
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700109 // Write-only, create file if non-existent.
110 static constexpr int kDstOpenFlags = O_WRONLY | O_CREAT;
111 // User R+W permission.
112 static constexpr int kDstFileMode = S_IRUSR | S_IWUSR;
113 // Asset directory
114 static const std::string kAssetDirectory = "/data/local/tmp/TranscodingBenchmark/";
115
Naveen Kumar Ponnusamy9535f592020-12-10 00:21:21 +0530116 // Transcoding configuration params to be logged
117 int64_t trackDurationUs = 0;
118 int32_t width = 0;
119 int32_t height = 0;
120 std::string sourceMime = "NA";
121 std::string targetMime = "NA";
122 bool includeAudio = false;
123 bool transcodeVideo = false;
124 int32_t targetBitrate = 0;
125
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700126 int srcFd = 0;
127 int dstFd = 0;
128
129 std::string srcPath = kAssetDirectory + srcFileName;
130 std::string dstPath = kAssetDirectory + dstFileName;
131
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700132 media_status_t status = AMEDIA_OK;
133
134 if ((srcFd = open(srcPath.c_str(), O_RDONLY)) < 0) {
135 state.SkipWithError("Unable to open source file");
136 goto exit;
137 }
138 if ((dstFd = open(dstPath.c_str(), kDstOpenFlags, kDstFileMode)) < 0) {
139 state.SkipWithError("Unable to open destination file");
140 goto exit;
141 }
142
143 for (auto _ : state) {
Naveen Kumar Ponnusamy78d362a2020-12-16 18:10:47 -0800144 auto callbacks = std::make_shared<TranscoderCallbacks>();
Chong Zhangbbb4eac2020-11-18 11:12:06 -0800145 auto transcoder = MediaTranscoder::create(callbacks);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700146
147 status = transcoder->configureSource(srcFd);
148 if (status != AMEDIA_OK) {
149 state.SkipWithError("Unable to configure transcoder source");
150 goto exit;
151 }
152
153 status = transcoder->configureDestination(dstFd);
154 if (status != AMEDIA_OK) {
155 state.SkipWithError("Unable to configure transcoder destination");
156 goto exit;
157 }
158
159 std::vector<std::shared_ptr<AMediaFormat>> trackFormats = transcoder->getTrackFormats();
160 for (int i = 0; i < trackFormats.size(); ++i) {
161 AMediaFormat* srcFormat = trackFormats[i].get();
162 AMediaFormat* dstFormat = nullptr;
163
164 const char* mime = nullptr;
165 if (!AMediaFormat_getString(srcFormat, AMEDIAFORMAT_KEY_MIME, &mime)) {
166 state.SkipWithError("Source track format does not have MIME type");
167 goto exit;
168 }
169
170 if (strncmp(mime, "video/", 6) == 0) {
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700171 int32_t frameCount;
172 if (AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) {
Naveen Kumar Ponnusamy0dbe8712020-12-16 23:31:38 -0800173 state.counters[PARAM_VIDEO_FRAME_RATE] = benchmark::Counter(
174 frameCount, benchmark::Counter::kIsIterationInvariantRate);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700175 }
Naveen Kumar Ponnusamy9535f592020-12-10 00:21:21 +0530176 if (!AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_WIDTH, &width)) {
177 state.SkipWithError("Video source track format does not have width");
178 goto exit;
179 }
180 if (!AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_HEIGHT, &height)) {
181 state.SkipWithError("Video source track format does not have height");
182 goto exit;
183 }
184 AMediaFormat_getInt64(srcFormat, AMEDIAFORMAT_KEY_DURATION, &trackDurationUs);
185 sourceMime = mime;
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700186 }
187
Linus Nilsson16d772b2020-09-29 19:21:11 -0700188 if (trackSelectionCallback(mime, &dstFormat)) {
189 status = transcoder->configureTrackFormat(i, dstFormat);
Naveen Kumar Ponnusamy9535f592020-12-10 00:21:21 +0530190 if (strncmp(mime, "video/", 6) == 0 && dstFormat != nullptr) {
191 const char* mime = nullptr;
192 if (AMediaFormat_getString(dstFormat, AMEDIAFORMAT_KEY_MIME, &mime)) {
193 targetMime = mime;
194 }
195 AMediaFormat_getInt32(dstFormat, AMEDIAFORMAT_KEY_BIT_RATE, &targetBitrate);
196 transcodeVideo = true;
197 } else if (strncmp(mime, "audio/", 6) == 0) {
198 includeAudio = true;
199 }
Linus Nilsson16d772b2020-09-29 19:21:11 -0700200 }
201
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700202 if (dstFormat != nullptr) {
203 AMediaFormat_delete(dstFormat);
204 }
205 if (status != AMEDIA_OK) {
206 state.SkipWithError("Unable to configure track");
207 goto exit;
208 }
209 }
210
211 status = transcoder->start();
212 if (status != AMEDIA_OK) {
213 state.SkipWithError("Unable to start transcoder");
214 goto exit;
215 }
216
217 if (!callbacks->waitForTranscodingFinished()) {
Linus Nilssonb09aac22020-07-29 11:56:53 -0700218 transcoder->cancel();
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700219 state.SkipWithError("Transcoder timed out");
220 goto exit;
221 }
222 if (callbacks->mStatus != AMEDIA_OK) {
223 state.SkipWithError("Transcoder error when running");
224 goto exit;
225 }
226 }
227
Naveen Kumar Ponnusamy9535f592020-12-10 00:21:21 +0530228 // Set transcoding configuration params in benchmark label
229 state.SetLabel(srcFileName + "," +
230 std::to_string(width) + "x" + std::to_string(height) + "," +
231 sourceMime + "," +
232 std::to_string(trackDurationUs/1000) + "," +
233 (includeAudio ? "Yes" : "No") + "," +
234 (transcodeVideo ? "Yes" : "No") + "," +
235 targetMime + "," +
236 std::to_string(targetBitrate)
237 );
238
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700239exit:
240 if (srcFd > 0) close(srcFd);
241 if (dstFd > 0) close(dstFd);
242}
243
Linus Nilsson6bf46532020-10-07 11:58:02 -0700244/**
245 * Callback to edit track format for transcoding.
246 * @param dstFormat The default track format for the track type.
247 */
248using TrackFormatEditCallback = std::function<void(AMediaFormat* dstFormat)>;
249
Linus Nilsson16d772b2020-09-29 19:21:11 -0700250static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName,
251 const std::string& dstFileName, bool includeAudio,
Linus Nilsson6bf46532020-10-07 11:58:02 -0700252 bool transcodeVideo,
253 const TrackFormatEditCallback& videoFormatEditor = nullptr) {
Linus Nilsson16d772b2020-09-29 19:21:11 -0700254 TranscodeMediaFile(state, srcFileName, dstFileName,
255 [=](const char* mime, AMediaFormat** dstFormatOut) -> bool {
256 *dstFormatOut = nullptr;
257 if (strncmp(mime, "video/", 6) == 0 && transcodeVideo) {
258 *dstFormatOut = CreateDefaultVideoFormat();
Linus Nilsson6bf46532020-10-07 11:58:02 -0700259 if (videoFormatEditor != nullptr) {
260 videoFormatEditor(*dstFormatOut);
261 }
Linus Nilsson16d772b2020-09-29 19:21:11 -0700262 } else if (strncmp(mime, "audio/", 6) == 0 && !includeAudio) {
263 return false;
264 }
265 return true;
266 });
267}
268
Linus Nilsson6bf46532020-10-07 11:58:02 -0700269static void SetMaxOperatingRate(AMediaFormat* format) {
Linus Nilsson4aef0de2021-01-29 17:58:55 -0800270 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700271 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
272}
273
274//-------------------------------- AVC to AVC Benchmarks -------------------------------------------
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700275
276static void BM_TranscodeAvc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
277 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
278 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4",
Linus Nilsson16d772b2020-09-29 19:21:11 -0700279 true /* includeAudio */, true /* transcodeVideo */);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700280}
281
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700282static void BM_TranscodeAvc2AvcVideo2Video(benchmark::State& state) {
283 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
284 "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4",
Linus Nilsson16d772b2020-09-29 19:21:11 -0700285 false /* includeAudio */, true /* transcodeVideo */);
286}
287
288static void BM_TranscodeAvc2AvcAV2AVMaxOperatingRate(benchmark::State& state) {
289 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
290 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4",
Linus Nilsson6bf46532020-10-07 11:58:02 -0700291 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
Linus Nilsson16d772b2020-09-29 19:21:11 -0700292}
293
294static void BM_TranscodeAvc2AvcV2VMaxOperatingRate(benchmark::State& state) {
295 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
296 "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4",
Linus Nilsson6bf46532020-10-07 11:58:02 -0700297 false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700298}
299
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700300static void BM_TranscodeAvc2AvcAV2AV720P(benchmark::State& state) {
301 TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4",
302 "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4",
303 true /* includeAudio */, true /* transcodeVideo */);
304}
305
306static void BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) {
307 TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4",
308 "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4",
309 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
310}
Linus Nilsson6bf46532020-10-07 11:58:02 -0700311//-------------------------------- HEVC to AVC Benchmarks ------------------------------------------
312
313static void BM_TranscodeHevc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
314 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4",
315 "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4",
316 true /* includeAudio */, true /* transcodeVideo */);
317}
318
319static void BM_TranscodeHevc2AvcVideo2Video(benchmark::State& state) {
320 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4",
321 "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4",
322 false /* includeAudio */, true /* transcodeVideo */);
323}
324
325static void BM_TranscodeHevc2AvcAV2AVMaxOperatingRate(benchmark::State& state) {
326 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4",
327 "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4",
328 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
329}
330
331static void BM_TranscodeHevc2AvcV2VMaxOperatingRate(benchmark::State& state) {
332 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4",
333 "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4",
334 false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
335}
336
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700337static void BM_TranscodeHevc2AvcAV2AV720P(benchmark::State& state) {
338 TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4",
339 "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4",
340 true /* includeAudio */, true /* transcodeVideo */);
341}
342
343static void BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) {
344 TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4",
345 "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4",
346 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
347}
348
Linus Nilsson6bf46532020-10-07 11:58:02 -0700349//-------------------------------- Passthrough Benchmarks ------------------------------------------
350
Linus Nilsson6233fed2020-08-13 15:15:14 -0700351static void BM_TranscodeAudioVideoPassthrough(benchmark::State& state) {
352 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
353 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_passthrough_AV.mp4",
354 true /* includeAudio */, false /* transcodeVideo */);
355}
356static void BM_TranscodeVideoPassthrough(benchmark::State& state) {
357 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
358 "video_1920x1080_3648frame_h264_22Mbps_30fps_passthrough_AV.mp4",
359 false /* includeAudio */, false /* transcodeVideo */);
360}
361
Naveen Kumar Ponnusamy82e14782020-12-16 10:50:43 -0800362//---------------------------- Codecs, Resolutions, Bitrate ---------------------------------------
363static void SetMimeBitrate(AMediaFormat* format, std::string mime, int32_t bitrate) {
364 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime.c_str());
365 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
366}
367
368static void BM_1920x1080_Avc22Mbps2Avc12Mbps(benchmark::State& state) {
369 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_22Mbps.mp4",
370 "tx_bm_1920_1080_30fps_h264_22Mbps_transcoded_h264_12Mbps.mp4",
371 false /* includeAudio */, true /* transcodeVideo */,
372 [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
373 SetMimeBitrate(dstFormat, mime, bitrate);
374 });
375}
376
377static void BM_1920x1080_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
378 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
379 "tx_bm_1920_1080_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
380 false /* includeAudio */, true /* transcodeVideo */,
381 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
382 SetMimeBitrate(dstFormat, mime, bitrate);
383 });
384}
385
386static void BM_1920x1080_Avc15Mbps2AvcPassthrough(benchmark::State& state) {
387 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
388 "tx_bm_1920_1080_30fps_h264_15Mbps_passthrough_V.mp4",
389 false /* includeAudio */, false /* transcodeVideo */);
390}
391
392static void BM_1920x1080_Avc15MbpsAac2Avc8Mbps(benchmark::State& state) {
393 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
394 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps.mp4",
395 false /* includeAudio */, true /* transcodeVideo */,
396 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
397 SetMimeBitrate(dstFormat, mime, bitrate);
398 });
399}
400
401static void BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac(benchmark::State& state) {
402 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
403 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps_aac.mp4",
404 true /* includeAudio */, true /* transcodeVideo */,
405 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
406 SetMimeBitrate(dstFormat, mime, bitrate);
407 });
408}
409
410static void BM_1920x1080_Avc15MbpsAac2AvcPassthrough(benchmark::State& state) {
411 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
412 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_V.mp4",
413 false /* includeAudio */, false /* transcodeVideo */);
414}
415
416static void BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough(benchmark::State& state) {
417 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
418 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_AV.mp4",
419 true /* includeAudio */, false /* transcodeVideo */);
420}
421
422static void BM_1920x1080_Hevc17Mbps2Hevc8Mbps(benchmark::State& state) {
423 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
424 "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_hevc_8Mbps.mp4",
425 false /* includeAudio */, true /* transcodeVideo */,
426 [mime = "video/hevc", bitrate = 8000000](AMediaFormat* dstFormat) {
427 SetMimeBitrate(dstFormat, mime, bitrate);
428 });
429}
430
431static void BM_1920x1080_Hevc17Mbps2Avc12Mbps(benchmark::State& state) {
432 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
433 "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_h264_12Mbps.mp4",
434 false /* includeAudio */, true /* transcodeVideo */,
435 [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
436 SetMimeBitrate(dstFormat, mime, bitrate);
437 });
438}
439
440static void BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps(benchmark::State& state) {
441 TranscodeMediaFile(state, "tx_bm_1920_1080_60fps_hevc_28Mbps.mp4",
442 "tx_bm_1920_1080_60fps_hevc_28Mbps_transcoded_h264_15Mbps.mp4",
443 false /* includeAudio */, true /* transcodeVideo */,
444 [mime = "video/avc", bitrate = 15000000](AMediaFormat* dstFormat) {
445 SetMimeBitrate(dstFormat, mime, bitrate);
446 });
447}
448
449static void BM_1280x720_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
450 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
451 "tx_bm_1280_720_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
452 false /* includeAudio */, true /* transcodeVideo */,
453 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
454 SetMimeBitrate(dstFormat, mime, bitrate);
455 });
456}
457
458static void BM_1280x720_Avc10Mbps2AvcPassthrough(benchmark::State& state) {
459 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
460 "tx_bm_1280_720_30fps_h264_10Mbps_passthrough_V.mp4",
461 false /* includeAudio */, false /* transcodeVideo */);
462}
463
464static void BM_1280x720_Avc10MbpsAac2Avc4Mbps(benchmark::State& state) {
465 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
466 "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps.mp4",
467 false /* includeAudio */, true /* transcodeVideo */,
468 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
469 SetMimeBitrate(dstFormat, mime, bitrate);
470 });
471}
472
473static void BM_1280x720_Avc10MbpsAac2Avc4MbpsAac(benchmark::State& state) {
474 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
475 "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps_aac.mp4",
476 true /* includeAudio */, true /* transcodeVideo */,
477 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
478 SetMimeBitrate(dstFormat, mime, bitrate);
479 });
480}
481
482static void BM_1280x720_Avc10MbpsAac2AvcPassthrough(benchmark::State& state) {
483 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
484 "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_V.mp4",
485 false /* includeAudio */, false /* transcodeVideo */);
486}
487
488static void BM_1280x720_Avc10MbpsAac2AvcAacPassthrough(benchmark::State& state) {
489 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
490 "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_AV.mp4",
491 true /* includeAudio */, false /* transcodeVideo */);
492}
493
494static void BM_1280x720_Hevc8Mbps2Avc4Mbps(benchmark::State& state) {
495 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_hevc_8Mbps.mp4",
496 "tx_bm_1280_720_30fps_hevc_8Mbps_transcoded_h264_4Mbps.mp4",
497 false /* includeAudio */, true /* transcodeVideo */,
498 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
499 SetMimeBitrate(dstFormat, mime, bitrate);
500 });
501}
502
503static void BM_1080x1920_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
504 TranscodeMediaFile(state, "tx_bm_1080_1920_30fps_h264_15Mbps.mp4",
505 "tx_bm_1080_1920_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
506 false /* includeAudio */, true /* transcodeVideo */,
507 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
508 SetMimeBitrate(dstFormat, mime, bitrate);
509 });
510}
511
512static void BM_720x1280_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
513 TranscodeMediaFile(state, "tx_bm_720_1280_30fps_h264_10Mbps.mp4",
514 "tx_bm_720_1280_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
515 false /* includeAudio */, true /* transcodeVideo */,
516 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
517 SetMimeBitrate(dstFormat, mime, bitrate);
518 });
519}
520
521static void BM_3840x2160_Hevc42Mbps2Avc20Mbps(benchmark::State& state) {
522 TranscodeMediaFile(state, "tx_bm_3840_2160_30fps_hevc_42Mbps.mp4",
523 "tx_bm_3840_2160_30fps_hevc_42Mbps_transcoded_h264_4Mbps.mp4",
524 false /* includeAudio */, true /* transcodeVideo */,
525 [mime = "video/avc", bitrate = 20000000](AMediaFormat* dstFormat) {
526 SetMimeBitrate(dstFormat, mime, bitrate);
527 });
528}
529
Linus Nilsson6bf46532020-10-07 11:58:02 -0700530//-------------------------------- Benchmark Registration ------------------------------------------
531
532// Benchmark registration wrapper for transcoding.
533#define TRANSCODER_BENCHMARK(func) \
534 BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)
535
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700536TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAudioVideo2AudioVideo);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700537TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcVideo2Video);
Linus Nilsson16d772b2020-09-29 19:21:11 -0700538TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AVMaxOperatingRate);
539TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcV2VMaxOperatingRate);
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700540TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720P);
541TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700542
543TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAudioVideo2AudioVideo);
544TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcVideo2Video);
545TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AVMaxOperatingRate);
546TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcV2VMaxOperatingRate);
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700547TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720P);
548TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700549
Linus Nilsson6233fed2020-08-13 15:15:14 -0700550TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough);
551TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700552
Naveen Kumar Ponnusamy82e14782020-12-16 10:50:43 -0800553TRANSCODER_BENCHMARK(BM_1920x1080_Avc22Mbps2Avc12Mbps);
554TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2Avc8Mbps);
555TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2AvcPassthrough);
556TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8Mbps);
557TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac);
558TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcPassthrough);
559TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough);
560TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Hevc8Mbps);
561TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Avc12Mbps);
562TRANSCODER_BENCHMARK(BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps);
563
564TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2Avc4Mbps);
565TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2AvcPassthrough);
566TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4Mbps);
567TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4MbpsAac);
568TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcPassthrough);
569TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcAacPassthrough);
570TRANSCODER_BENCHMARK(BM_1280x720_Hevc8Mbps2Avc4Mbps);
571
572TRANSCODER_BENCHMARK(BM_1080x1920_Avc15Mbps2Avc8Mbps);
573TRANSCODER_BENCHMARK(BM_720x1280_Avc10Mbps2Avc4Mbps);
574
575TRANSCODER_BENCHMARK(BM_3840x2160_Hevc42Mbps2Avc20Mbps);
576
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530577class CustomCsvReporter : public benchmark::BenchmarkReporter {
578public:
579 CustomCsvReporter() : mPrintedHeader(false) {}
580 virtual bool ReportContext(const Context& context);
581 virtual void ReportRuns(const std::vector<Run>& reports);
582
583private:
584 void PrintRunData(const Run& report);
585
586 bool mPrintedHeader;
Naveen Kumar Ponnusamy9535f592020-12-10 00:21:21 +0530587 std::vector<std::string> mHeaders = {
588 "File", "Resolution", "SourceMime", "VideoTrackDuration(ms)",
589 "IncludeAudio", "TranscodeVideo", "TargetMime", "TargetBirate(bps)",
590 "real_time(ms)", "cpu_time(ms)", PARAM_VIDEO_FRAME_RATE
591 };
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530592};
593
594bool CustomCsvReporter::ReportContext(const Context& context __unused) {
595 return true;
596}
597
598void CustomCsvReporter::ReportRuns(const std::vector<Run>& reports) {
599 std::ostream& Out = GetOutputStream();
600
601 if (!mPrintedHeader) {
602 // print the header
603 for (auto header = mHeaders.begin(); header != mHeaders.end();) {
604 Out << *header++;
605 if (header != mHeaders.end()) Out << ",";
606 }
607 Out << "\n";
608 mPrintedHeader = true;
609 }
610
611 // print results for each run
612 for (const auto& run : reports) {
613 PrintRunData(run);
614 }
615}
616
617void CustomCsvReporter::PrintRunData(const Run& run) {
618 if (run.error_occurred) {
619 return;
620 }
621 std::ostream& Out = GetOutputStream();
Naveen Kumar Ponnusamy9535f592020-12-10 00:21:21 +0530622 // Log the transcoding params reported through label
623 Out << run.report_label << ",";
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530624 Out << run.GetAdjustedRealTime() << ",";
625 Out << run.GetAdjustedCPUTime() << ",";
626 auto frameRate = run.counters.find(PARAM_VIDEO_FRAME_RATE);
627 if (frameRate == run.counters.end()) {
628 Out << "NA"
629 << ",";
630 } else {
631 Out << frameRate->second << ",";
632 }
633 Out << '\n';
634}
635
636int main(int argc, char** argv) {
Naveen Kumar Ponnusamy2d074ba2020-12-17 17:13:45 -0800637 android::ProcessState::self()->startThreadPool();
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530638 std::unique_ptr<benchmark::BenchmarkReporter> fileReporter;
639 for (int i = 1; i < argc; ++i) {
640 if (std::string(argv[i]).find("--benchmark_out") != std::string::npos) {
641 fileReporter.reset(new CustomCsvReporter);
642 break;
643 }
644 }
645 ::benchmark::Initialize(&argc, argv);
646 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
647 ::benchmark::RunSpecifiedBenchmarks(nullptr, fileReporter.get());
648}