blob: ac3b2c0f5026dce0b2ecfea807d0ca0d92cb894e [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
116 int srcFd = 0;
117 int dstFd = 0;
118
119 std::string srcPath = kAssetDirectory + srcFileName;
120 std::string dstPath = kAssetDirectory + dstFileName;
121
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700122 media_status_t status = AMEDIA_OK;
123
124 if ((srcFd = open(srcPath.c_str(), O_RDONLY)) < 0) {
125 state.SkipWithError("Unable to open source file");
126 goto exit;
127 }
128 if ((dstFd = open(dstPath.c_str(), kDstOpenFlags, kDstFileMode)) < 0) {
129 state.SkipWithError("Unable to open destination file");
130 goto exit;
131 }
132
133 for (auto _ : state) {
Naveen Kumar Ponnusamy78d362a2020-12-16 18:10:47 -0800134 auto callbacks = std::make_shared<TranscoderCallbacks>();
Chong Zhangbbb4eac2020-11-18 11:12:06 -0800135 auto transcoder = MediaTranscoder::create(callbacks);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700136
137 status = transcoder->configureSource(srcFd);
138 if (status != AMEDIA_OK) {
139 state.SkipWithError("Unable to configure transcoder source");
140 goto exit;
141 }
142
143 status = transcoder->configureDestination(dstFd);
144 if (status != AMEDIA_OK) {
145 state.SkipWithError("Unable to configure transcoder destination");
146 goto exit;
147 }
148
149 std::vector<std::shared_ptr<AMediaFormat>> trackFormats = transcoder->getTrackFormats();
150 for (int i = 0; i < trackFormats.size(); ++i) {
151 AMediaFormat* srcFormat = trackFormats[i].get();
152 AMediaFormat* dstFormat = nullptr;
153
154 const char* mime = nullptr;
155 if (!AMediaFormat_getString(srcFormat, AMEDIAFORMAT_KEY_MIME, &mime)) {
156 state.SkipWithError("Source track format does not have MIME type");
157 goto exit;
158 }
159
160 if (strncmp(mime, "video/", 6) == 0) {
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700161 int32_t frameCount;
162 if (AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) {
Naveen Kumar Ponnusamy0dbe8712020-12-16 23:31:38 -0800163 state.counters[PARAM_VIDEO_FRAME_RATE] = benchmark::Counter(
164 frameCount, benchmark::Counter::kIsIterationInvariantRate);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700165 }
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700166 }
167
Linus Nilsson16d772b2020-09-29 19:21:11 -0700168 if (trackSelectionCallback(mime, &dstFormat)) {
169 status = transcoder->configureTrackFormat(i, dstFormat);
170 }
171
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700172 if (dstFormat != nullptr) {
173 AMediaFormat_delete(dstFormat);
174 }
175 if (status != AMEDIA_OK) {
176 state.SkipWithError("Unable to configure track");
177 goto exit;
178 }
179 }
180
181 status = transcoder->start();
182 if (status != AMEDIA_OK) {
183 state.SkipWithError("Unable to start transcoder");
184 goto exit;
185 }
186
187 if (!callbacks->waitForTranscodingFinished()) {
Linus Nilssonb09aac22020-07-29 11:56:53 -0700188 transcoder->cancel();
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700189 state.SkipWithError("Transcoder timed out");
190 goto exit;
191 }
192 if (callbacks->mStatus != AMEDIA_OK) {
193 state.SkipWithError("Transcoder error when running");
194 goto exit;
195 }
196 }
197
198exit:
199 if (srcFd > 0) close(srcFd);
200 if (dstFd > 0) close(dstFd);
201}
202
Linus Nilsson6bf46532020-10-07 11:58:02 -0700203/**
204 * Callback to edit track format for transcoding.
205 * @param dstFormat The default track format for the track type.
206 */
207using TrackFormatEditCallback = std::function<void(AMediaFormat* dstFormat)>;
208
Linus Nilsson16d772b2020-09-29 19:21:11 -0700209static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName,
210 const std::string& dstFileName, bool includeAudio,
Linus Nilsson6bf46532020-10-07 11:58:02 -0700211 bool transcodeVideo,
212 const TrackFormatEditCallback& videoFormatEditor = nullptr) {
Linus Nilsson16d772b2020-09-29 19:21:11 -0700213 TranscodeMediaFile(state, srcFileName, dstFileName,
214 [=](const char* mime, AMediaFormat** dstFormatOut) -> bool {
215 *dstFormatOut = nullptr;
216 if (strncmp(mime, "video/", 6) == 0 && transcodeVideo) {
217 *dstFormatOut = CreateDefaultVideoFormat();
Linus Nilsson6bf46532020-10-07 11:58:02 -0700218 if (videoFormatEditor != nullptr) {
219 videoFormatEditor(*dstFormatOut);
220 }
Linus Nilsson16d772b2020-09-29 19:21:11 -0700221 } else if (strncmp(mime, "audio/", 6) == 0 && !includeAudio) {
222 return false;
223 }
224 return true;
225 });
226}
227
Linus Nilsson6bf46532020-10-07 11:58:02 -0700228static void SetMaxOperatingRate(AMediaFormat* format) {
Linus Nilsson4aef0de2021-01-29 17:58:55 -0800229 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700230 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
231}
232
233//-------------------------------- AVC to AVC Benchmarks -------------------------------------------
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700234
235static void BM_TranscodeAvc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
236 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
237 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4",
Linus Nilsson16d772b2020-09-29 19:21:11 -0700238 true /* includeAudio */, true /* transcodeVideo */);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700239}
240
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700241static void BM_TranscodeAvc2AvcVideo2Video(benchmark::State& state) {
242 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
243 "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4",
Linus Nilsson16d772b2020-09-29 19:21:11 -0700244 false /* includeAudio */, true /* transcodeVideo */);
245}
246
247static void BM_TranscodeAvc2AvcAV2AVMaxOperatingRate(benchmark::State& state) {
248 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
249 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4",
Linus Nilsson6bf46532020-10-07 11:58:02 -0700250 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
Linus Nilsson16d772b2020-09-29 19:21:11 -0700251}
252
253static void BM_TranscodeAvc2AvcV2VMaxOperatingRate(benchmark::State& state) {
254 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
255 "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4",
Linus Nilsson6bf46532020-10-07 11:58:02 -0700256 false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700257}
258
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700259static void BM_TranscodeAvc2AvcAV2AV720P(benchmark::State& state) {
260 TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4",
261 "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4",
262 true /* includeAudio */, true /* transcodeVideo */);
263}
264
265static void BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) {
266 TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4",
267 "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4",
268 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
269}
Linus Nilsson6bf46532020-10-07 11:58:02 -0700270//-------------------------------- HEVC to AVC Benchmarks ------------------------------------------
271
272static void BM_TranscodeHevc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
273 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4",
274 "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4",
275 true /* includeAudio */, true /* transcodeVideo */);
276}
277
278static void BM_TranscodeHevc2AvcVideo2Video(benchmark::State& state) {
279 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4",
280 "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4",
281 false /* includeAudio */, true /* transcodeVideo */);
282}
283
284static void BM_TranscodeHevc2AvcAV2AVMaxOperatingRate(benchmark::State& state) {
285 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4",
286 "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4",
287 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
288}
289
290static void BM_TranscodeHevc2AvcV2VMaxOperatingRate(benchmark::State& state) {
291 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4",
292 "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4",
293 false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
294}
295
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700296static void BM_TranscodeHevc2AvcAV2AV720P(benchmark::State& state) {
297 TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4",
298 "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4",
299 true /* includeAudio */, true /* transcodeVideo */);
300}
301
302static void BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) {
303 TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4",
304 "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4",
305 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
306}
307
Linus Nilsson6bf46532020-10-07 11:58:02 -0700308//-------------------------------- Passthrough Benchmarks ------------------------------------------
309
Linus Nilsson6233fed2020-08-13 15:15:14 -0700310static void BM_TranscodeAudioVideoPassthrough(benchmark::State& state) {
311 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
312 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_passthrough_AV.mp4",
313 true /* includeAudio */, false /* transcodeVideo */);
314}
315static void BM_TranscodeVideoPassthrough(benchmark::State& state) {
316 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
317 "video_1920x1080_3648frame_h264_22Mbps_30fps_passthrough_AV.mp4",
318 false /* includeAudio */, false /* transcodeVideo */);
319}
320
Naveen Kumar Ponnusamy82e14782020-12-16 10:50:43 -0800321//---------------------------- Codecs, Resolutions, Bitrate ---------------------------------------
322static void SetMimeBitrate(AMediaFormat* format, std::string mime, int32_t bitrate) {
323 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime.c_str());
324 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
325}
326
327static void BM_1920x1080_Avc22Mbps2Avc12Mbps(benchmark::State& state) {
328 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_22Mbps.mp4",
329 "tx_bm_1920_1080_30fps_h264_22Mbps_transcoded_h264_12Mbps.mp4",
330 false /* includeAudio */, true /* transcodeVideo */,
331 [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
332 SetMimeBitrate(dstFormat, mime, bitrate);
333 });
334}
335
336static void BM_1920x1080_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
337 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
338 "tx_bm_1920_1080_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
339 false /* includeAudio */, true /* transcodeVideo */,
340 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
341 SetMimeBitrate(dstFormat, mime, bitrate);
342 });
343}
344
345static void BM_1920x1080_Avc15Mbps2AvcPassthrough(benchmark::State& state) {
346 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
347 "tx_bm_1920_1080_30fps_h264_15Mbps_passthrough_V.mp4",
348 false /* includeAudio */, false /* transcodeVideo */);
349}
350
351static void BM_1920x1080_Avc15MbpsAac2Avc8Mbps(benchmark::State& state) {
352 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
353 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps.mp4",
354 false /* includeAudio */, true /* transcodeVideo */,
355 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
356 SetMimeBitrate(dstFormat, mime, bitrate);
357 });
358}
359
360static void BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac(benchmark::State& state) {
361 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
362 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps_aac.mp4",
363 true /* includeAudio */, true /* transcodeVideo */,
364 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
365 SetMimeBitrate(dstFormat, mime, bitrate);
366 });
367}
368
369static void BM_1920x1080_Avc15MbpsAac2AvcPassthrough(benchmark::State& state) {
370 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
371 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_V.mp4",
372 false /* includeAudio */, false /* transcodeVideo */);
373}
374
375static void BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough(benchmark::State& state) {
376 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
377 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_AV.mp4",
378 true /* includeAudio */, false /* transcodeVideo */);
379}
380
381static void BM_1920x1080_Hevc17Mbps2Hevc8Mbps(benchmark::State& state) {
382 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
383 "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_hevc_8Mbps.mp4",
384 false /* includeAudio */, true /* transcodeVideo */,
385 [mime = "video/hevc", bitrate = 8000000](AMediaFormat* dstFormat) {
386 SetMimeBitrate(dstFormat, mime, bitrate);
387 });
388}
389
390static void BM_1920x1080_Hevc17Mbps2Avc12Mbps(benchmark::State& state) {
391 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
392 "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_h264_12Mbps.mp4",
393 false /* includeAudio */, true /* transcodeVideo */,
394 [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
395 SetMimeBitrate(dstFormat, mime, bitrate);
396 });
397}
398
399static void BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps(benchmark::State& state) {
400 TranscodeMediaFile(state, "tx_bm_1920_1080_60fps_hevc_28Mbps.mp4",
401 "tx_bm_1920_1080_60fps_hevc_28Mbps_transcoded_h264_15Mbps.mp4",
402 false /* includeAudio */, true /* transcodeVideo */,
403 [mime = "video/avc", bitrate = 15000000](AMediaFormat* dstFormat) {
404 SetMimeBitrate(dstFormat, mime, bitrate);
405 });
406}
407
408static void BM_1280x720_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
409 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
410 "tx_bm_1280_720_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
411 false /* includeAudio */, true /* transcodeVideo */,
412 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
413 SetMimeBitrate(dstFormat, mime, bitrate);
414 });
415}
416
417static void BM_1280x720_Avc10Mbps2AvcPassthrough(benchmark::State& state) {
418 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
419 "tx_bm_1280_720_30fps_h264_10Mbps_passthrough_V.mp4",
420 false /* includeAudio */, false /* transcodeVideo */);
421}
422
423static void BM_1280x720_Avc10MbpsAac2Avc4Mbps(benchmark::State& state) {
424 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
425 "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps.mp4",
426 false /* includeAudio */, true /* transcodeVideo */,
427 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
428 SetMimeBitrate(dstFormat, mime, bitrate);
429 });
430}
431
432static void BM_1280x720_Avc10MbpsAac2Avc4MbpsAac(benchmark::State& state) {
433 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
434 "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps_aac.mp4",
435 true /* includeAudio */, true /* transcodeVideo */,
436 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
437 SetMimeBitrate(dstFormat, mime, bitrate);
438 });
439}
440
441static void BM_1280x720_Avc10MbpsAac2AvcPassthrough(benchmark::State& state) {
442 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
443 "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_V.mp4",
444 false /* includeAudio */, false /* transcodeVideo */);
445}
446
447static void BM_1280x720_Avc10MbpsAac2AvcAacPassthrough(benchmark::State& state) {
448 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
449 "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_AV.mp4",
450 true /* includeAudio */, false /* transcodeVideo */);
451}
452
453static void BM_1280x720_Hevc8Mbps2Avc4Mbps(benchmark::State& state) {
454 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_hevc_8Mbps.mp4",
455 "tx_bm_1280_720_30fps_hevc_8Mbps_transcoded_h264_4Mbps.mp4",
456 false /* includeAudio */, true /* transcodeVideo */,
457 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
458 SetMimeBitrate(dstFormat, mime, bitrate);
459 });
460}
461
462static void BM_1080x1920_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
463 TranscodeMediaFile(state, "tx_bm_1080_1920_30fps_h264_15Mbps.mp4",
464 "tx_bm_1080_1920_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
465 false /* includeAudio */, true /* transcodeVideo */,
466 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
467 SetMimeBitrate(dstFormat, mime, bitrate);
468 });
469}
470
471static void BM_720x1280_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
472 TranscodeMediaFile(state, "tx_bm_720_1280_30fps_h264_10Mbps.mp4",
473 "tx_bm_720_1280_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
474 false /* includeAudio */, true /* transcodeVideo */,
475 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
476 SetMimeBitrate(dstFormat, mime, bitrate);
477 });
478}
479
480static void BM_3840x2160_Hevc42Mbps2Avc20Mbps(benchmark::State& state) {
481 TranscodeMediaFile(state, "tx_bm_3840_2160_30fps_hevc_42Mbps.mp4",
482 "tx_bm_3840_2160_30fps_hevc_42Mbps_transcoded_h264_4Mbps.mp4",
483 false /* includeAudio */, true /* transcodeVideo */,
484 [mime = "video/avc", bitrate = 20000000](AMediaFormat* dstFormat) {
485 SetMimeBitrate(dstFormat, mime, bitrate);
486 });
487}
488
Linus Nilsson6bf46532020-10-07 11:58:02 -0700489//-------------------------------- Benchmark Registration ------------------------------------------
490
491// Benchmark registration wrapper for transcoding.
492#define TRANSCODER_BENCHMARK(func) \
493 BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)
494
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700495TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAudioVideo2AudioVideo);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700496TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcVideo2Video);
Linus Nilsson16d772b2020-09-29 19:21:11 -0700497TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AVMaxOperatingRate);
498TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcV2VMaxOperatingRate);
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700499TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720P);
500TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700501
502TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAudioVideo2AudioVideo);
503TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcVideo2Video);
504TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AVMaxOperatingRate);
505TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcV2VMaxOperatingRate);
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700506TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720P);
507TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700508
Linus Nilsson6233fed2020-08-13 15:15:14 -0700509TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough);
510TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700511
Naveen Kumar Ponnusamy82e14782020-12-16 10:50:43 -0800512TRANSCODER_BENCHMARK(BM_1920x1080_Avc22Mbps2Avc12Mbps);
513TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2Avc8Mbps);
514TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2AvcPassthrough);
515TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8Mbps);
516TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac);
517TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcPassthrough);
518TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough);
519TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Hevc8Mbps);
520TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Avc12Mbps);
521TRANSCODER_BENCHMARK(BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps);
522
523TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2Avc4Mbps);
524TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2AvcPassthrough);
525TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4Mbps);
526TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4MbpsAac);
527TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcPassthrough);
528TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcAacPassthrough);
529TRANSCODER_BENCHMARK(BM_1280x720_Hevc8Mbps2Avc4Mbps);
530
531TRANSCODER_BENCHMARK(BM_1080x1920_Avc15Mbps2Avc8Mbps);
532TRANSCODER_BENCHMARK(BM_720x1280_Avc10Mbps2Avc4Mbps);
533
534TRANSCODER_BENCHMARK(BM_3840x2160_Hevc42Mbps2Avc20Mbps);
535
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530536class CustomCsvReporter : public benchmark::BenchmarkReporter {
537public:
538 CustomCsvReporter() : mPrintedHeader(false) {}
539 virtual bool ReportContext(const Context& context);
540 virtual void ReportRuns(const std::vector<Run>& reports);
541
542private:
543 void PrintRunData(const Run& report);
544
545 bool mPrintedHeader;
546 std::vector<std::string> mHeaders = {"name", "real_time", "cpu_time", PARAM_VIDEO_FRAME_RATE};
547};
548
549bool CustomCsvReporter::ReportContext(const Context& context __unused) {
550 return true;
551}
552
553void CustomCsvReporter::ReportRuns(const std::vector<Run>& reports) {
554 std::ostream& Out = GetOutputStream();
555
556 if (!mPrintedHeader) {
557 // print the header
558 for (auto header = mHeaders.begin(); header != mHeaders.end();) {
559 Out << *header++;
560 if (header != mHeaders.end()) Out << ",";
561 }
562 Out << "\n";
563 mPrintedHeader = true;
564 }
565
566 // print results for each run
567 for (const auto& run : reports) {
568 PrintRunData(run);
569 }
570}
571
572void CustomCsvReporter::PrintRunData(const Run& run) {
573 if (run.error_occurred) {
574 return;
575 }
576 std::ostream& Out = GetOutputStream();
577 Out << run.benchmark_name() << ",";
578 Out << run.GetAdjustedRealTime() << ",";
579 Out << run.GetAdjustedCPUTime() << ",";
580 auto frameRate = run.counters.find(PARAM_VIDEO_FRAME_RATE);
581 if (frameRate == run.counters.end()) {
582 Out << "NA"
583 << ",";
584 } else {
585 Out << frameRate->second << ",";
586 }
587 Out << '\n';
588}
589
590int main(int argc, char** argv) {
Naveen Kumar Ponnusamy2d074ba2020-12-17 17:13:45 -0800591 android::ProcessState::self()->startThreadPool();
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530592 std::unique_ptr<benchmark::BenchmarkReporter> fileReporter;
593 for (int i = 1; i < argc; ++i) {
594 if (std::string(argv[i]).find("--benchmark_out") != std::string::npos) {
595 fileReporter.reset(new CustomCsvReporter);
596 break;
597 }
598 }
599 ::benchmark::Initialize(&argc, argv);
600 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
601 ::benchmark::RunSpecifiedBenchmarks(nullptr, fileReporter.get());
602}