blob: 712f8fc2319d5c0d6191b1860e630d90d6435e9a [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
63 virtual void onCodecResourceLost(const MediaTranscoder* transcoder __unused,
Chong Zhange4e088f2020-10-21 19:10:42 -070064 const std::shared_ptr<ndk::ScopedAParcel>& pausedState
Linus Nilsson8f0b8762020-07-23 17:12:45 -070065 __unused) override {}
66
67 bool waitForTranscodingFinished() {
68 std::unique_lock<std::mutex> lock(mMutex);
69 while (!mFinished) {
70 if (mCondition.wait_for(lock, std::chrono::minutes(5)) == std::cv_status::timeout) {
71 return false;
72 }
73 }
74 return true;
75 }
76
77 media_status_t mStatus = AMEDIA_OK;
78
79private:
80 std::mutex mMutex;
81 std::condition_variable mCondition;
82 bool mFinished = false;
83};
84
Linus Nilsson16d772b2020-09-29 19:21:11 -070085static AMediaFormat* CreateDefaultVideoFormat() {
Linus Nilsson8f0b8762020-07-23 17:12:45 -070086 // Default bitrate
87 static constexpr int32_t kVideoBitRate = 20 * 1000 * 1000; // 20Mbs
Linus Nilsson16d772b2020-09-29 19:21:11 -070088
89 AMediaFormat* videoFormat = AMediaFormat_new();
90 AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate);
Linus Nilsson4aef0de2021-01-29 17:58:55 -080091 AMediaFormat_setString(videoFormat, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
Linus Nilsson16d772b2020-09-29 19:21:11 -070092 return videoFormat;
93}
94
95/**
96 * Callback to configure tracks for transcoding.
97 * @param mime The source track mime type.
98 * @param dstFormat The destination format if the track should be transcoded or nullptr if the track
99 * should be passed through.
100 * @return True if the track should be included in the output file.
101 */
102using TrackSelectionCallback = std::function<bool(const char* mime, AMediaFormat** dstFormat)>;
103
104static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName,
105 const std::string& dstFileName,
106 TrackSelectionCallback trackSelectionCallback) {
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700107 // Write-only, create file if non-existent.
108 static constexpr int kDstOpenFlags = O_WRONLY | O_CREAT;
109 // User R+W permission.
110 static constexpr int kDstFileMode = S_IRUSR | S_IWUSR;
111 // Asset directory
112 static const std::string kAssetDirectory = "/data/local/tmp/TranscodingBenchmark/";
113
114 int srcFd = 0;
115 int dstFd = 0;
116
117 std::string srcPath = kAssetDirectory + srcFileName;
118 std::string dstPath = kAssetDirectory + dstFileName;
119
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700120 media_status_t status = AMEDIA_OK;
121
122 if ((srcFd = open(srcPath.c_str(), O_RDONLY)) < 0) {
123 state.SkipWithError("Unable to open source file");
124 goto exit;
125 }
126 if ((dstFd = open(dstPath.c_str(), kDstOpenFlags, kDstFileMode)) < 0) {
127 state.SkipWithError("Unable to open destination file");
128 goto exit;
129 }
130
131 for (auto _ : state) {
Naveen Kumar Ponnusamy78d362a2020-12-16 18:10:47 -0800132 auto callbacks = std::make_shared<TranscoderCallbacks>();
Chong Zhangbbb4eac2020-11-18 11:12:06 -0800133 auto transcoder = MediaTranscoder::create(callbacks);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700134
135 status = transcoder->configureSource(srcFd);
136 if (status != AMEDIA_OK) {
137 state.SkipWithError("Unable to configure transcoder source");
138 goto exit;
139 }
140
141 status = transcoder->configureDestination(dstFd);
142 if (status != AMEDIA_OK) {
143 state.SkipWithError("Unable to configure transcoder destination");
144 goto exit;
145 }
146
147 std::vector<std::shared_ptr<AMediaFormat>> trackFormats = transcoder->getTrackFormats();
148 for (int i = 0; i < trackFormats.size(); ++i) {
149 AMediaFormat* srcFormat = trackFormats[i].get();
150 AMediaFormat* dstFormat = nullptr;
151
152 const char* mime = nullptr;
153 if (!AMediaFormat_getString(srcFormat, AMEDIAFORMAT_KEY_MIME, &mime)) {
154 state.SkipWithError("Source track format does not have MIME type");
155 goto exit;
156 }
157
158 if (strncmp(mime, "video/", 6) == 0) {
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700159 int32_t frameCount;
160 if (AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) {
Naveen Kumar Ponnusamy0dbe8712020-12-16 23:31:38 -0800161 state.counters[PARAM_VIDEO_FRAME_RATE] = benchmark::Counter(
162 frameCount, benchmark::Counter::kIsIterationInvariantRate);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700163 }
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700164 }
165
Linus Nilsson16d772b2020-09-29 19:21:11 -0700166 if (trackSelectionCallback(mime, &dstFormat)) {
167 status = transcoder->configureTrackFormat(i, dstFormat);
168 }
169
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700170 if (dstFormat != nullptr) {
171 AMediaFormat_delete(dstFormat);
172 }
173 if (status != AMEDIA_OK) {
174 state.SkipWithError("Unable to configure track");
175 goto exit;
176 }
177 }
178
179 status = transcoder->start();
180 if (status != AMEDIA_OK) {
181 state.SkipWithError("Unable to start transcoder");
182 goto exit;
183 }
184
185 if (!callbacks->waitForTranscodingFinished()) {
Linus Nilssonb09aac22020-07-29 11:56:53 -0700186 transcoder->cancel();
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700187 state.SkipWithError("Transcoder timed out");
188 goto exit;
189 }
190 if (callbacks->mStatus != AMEDIA_OK) {
191 state.SkipWithError("Transcoder error when running");
192 goto exit;
193 }
194 }
195
196exit:
197 if (srcFd > 0) close(srcFd);
198 if (dstFd > 0) close(dstFd);
199}
200
Linus Nilsson6bf46532020-10-07 11:58:02 -0700201/**
202 * Callback to edit track format for transcoding.
203 * @param dstFormat The default track format for the track type.
204 */
205using TrackFormatEditCallback = std::function<void(AMediaFormat* dstFormat)>;
206
Linus Nilsson16d772b2020-09-29 19:21:11 -0700207static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName,
208 const std::string& dstFileName, bool includeAudio,
Linus Nilsson6bf46532020-10-07 11:58:02 -0700209 bool transcodeVideo,
210 const TrackFormatEditCallback& videoFormatEditor = nullptr) {
Linus Nilsson16d772b2020-09-29 19:21:11 -0700211 TranscodeMediaFile(state, srcFileName, dstFileName,
212 [=](const char* mime, AMediaFormat** dstFormatOut) -> bool {
213 *dstFormatOut = nullptr;
214 if (strncmp(mime, "video/", 6) == 0 && transcodeVideo) {
215 *dstFormatOut = CreateDefaultVideoFormat();
Linus Nilsson6bf46532020-10-07 11:58:02 -0700216 if (videoFormatEditor != nullptr) {
217 videoFormatEditor(*dstFormatOut);
218 }
Linus Nilsson16d772b2020-09-29 19:21:11 -0700219 } else if (strncmp(mime, "audio/", 6) == 0 && !includeAudio) {
220 return false;
221 }
222 return true;
223 });
224}
225
Linus Nilsson6bf46532020-10-07 11:58:02 -0700226static void SetMaxOperatingRate(AMediaFormat* format) {
Linus Nilsson4aef0de2021-01-29 17:58:55 -0800227 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700228 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
229}
230
231//-------------------------------- AVC to AVC Benchmarks -------------------------------------------
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700232
233static void BM_TranscodeAvc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
234 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
235 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4",
Linus Nilsson16d772b2020-09-29 19:21:11 -0700236 true /* includeAudio */, true /* transcodeVideo */);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700237}
238
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700239static void BM_TranscodeAvc2AvcVideo2Video(benchmark::State& state) {
240 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
241 "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4",
Linus Nilsson16d772b2020-09-29 19:21:11 -0700242 false /* includeAudio */, true /* transcodeVideo */);
243}
244
245static void BM_TranscodeAvc2AvcAV2AVMaxOperatingRate(benchmark::State& state) {
246 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
247 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4",
Linus Nilsson6bf46532020-10-07 11:58:02 -0700248 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
Linus Nilsson16d772b2020-09-29 19:21:11 -0700249}
250
251static void BM_TranscodeAvc2AvcV2VMaxOperatingRate(benchmark::State& state) {
252 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
253 "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4",
Linus Nilsson6bf46532020-10-07 11:58:02 -0700254 false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700255}
256
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700257static void BM_TranscodeAvc2AvcAV2AV720P(benchmark::State& state) {
258 TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4",
259 "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4",
260 true /* includeAudio */, true /* transcodeVideo */);
261}
262
263static void BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) {
264 TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4",
265 "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4",
266 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
267}
Linus Nilsson6bf46532020-10-07 11:58:02 -0700268//-------------------------------- HEVC to AVC Benchmarks ------------------------------------------
269
270static void BM_TranscodeHevc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
271 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4",
272 "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4",
273 true /* includeAudio */, true /* transcodeVideo */);
274}
275
276static void BM_TranscodeHevc2AvcVideo2Video(benchmark::State& state) {
277 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4",
278 "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4",
279 false /* includeAudio */, true /* transcodeVideo */);
280}
281
282static void BM_TranscodeHevc2AvcAV2AVMaxOperatingRate(benchmark::State& state) {
283 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4",
284 "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4",
285 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
286}
287
288static void BM_TranscodeHevc2AvcV2VMaxOperatingRate(benchmark::State& state) {
289 TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4",
290 "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4",
291 false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
292}
293
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700294static void BM_TranscodeHevc2AvcAV2AV720P(benchmark::State& state) {
295 TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4",
296 "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4",
297 true /* includeAudio */, true /* transcodeVideo */);
298}
299
300static void BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) {
301 TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4",
302 "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4",
303 true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
304}
305
Linus Nilsson6bf46532020-10-07 11:58:02 -0700306//-------------------------------- Passthrough Benchmarks ------------------------------------------
307
Linus Nilsson6233fed2020-08-13 15:15:14 -0700308static void BM_TranscodeAudioVideoPassthrough(benchmark::State& state) {
309 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
310 "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_passthrough_AV.mp4",
311 true /* includeAudio */, false /* transcodeVideo */);
312}
313static void BM_TranscodeVideoPassthrough(benchmark::State& state) {
314 TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4",
315 "video_1920x1080_3648frame_h264_22Mbps_30fps_passthrough_AV.mp4",
316 false /* includeAudio */, false /* transcodeVideo */);
317}
318
Naveen Kumar Ponnusamy82e14782020-12-16 10:50:43 -0800319//---------------------------- Codecs, Resolutions, Bitrate ---------------------------------------
320static void SetMimeBitrate(AMediaFormat* format, std::string mime, int32_t bitrate) {
321 AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime.c_str());
322 AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate);
323}
324
325static void BM_1920x1080_Avc22Mbps2Avc12Mbps(benchmark::State& state) {
326 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_22Mbps.mp4",
327 "tx_bm_1920_1080_30fps_h264_22Mbps_transcoded_h264_12Mbps.mp4",
328 false /* includeAudio */, true /* transcodeVideo */,
329 [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
330 SetMimeBitrate(dstFormat, mime, bitrate);
331 });
332}
333
334static void BM_1920x1080_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
335 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
336 "tx_bm_1920_1080_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
337 false /* includeAudio */, true /* transcodeVideo */,
338 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
339 SetMimeBitrate(dstFormat, mime, bitrate);
340 });
341}
342
343static void BM_1920x1080_Avc15Mbps2AvcPassthrough(benchmark::State& state) {
344 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4",
345 "tx_bm_1920_1080_30fps_h264_15Mbps_passthrough_V.mp4",
346 false /* includeAudio */, false /* transcodeVideo */);
347}
348
349static void BM_1920x1080_Avc15MbpsAac2Avc8Mbps(benchmark::State& state) {
350 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
351 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps.mp4",
352 false /* includeAudio */, true /* transcodeVideo */,
353 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
354 SetMimeBitrate(dstFormat, mime, bitrate);
355 });
356}
357
358static void BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac(benchmark::State& state) {
359 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
360 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps_aac.mp4",
361 true /* includeAudio */, true /* transcodeVideo */,
362 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
363 SetMimeBitrate(dstFormat, mime, bitrate);
364 });
365}
366
367static void BM_1920x1080_Avc15MbpsAac2AvcPassthrough(benchmark::State& state) {
368 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
369 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_V.mp4",
370 false /* includeAudio */, false /* transcodeVideo */);
371}
372
373static void BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough(benchmark::State& state) {
374 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4",
375 "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_AV.mp4",
376 true /* includeAudio */, false /* transcodeVideo */);
377}
378
379static void BM_1920x1080_Hevc17Mbps2Hevc8Mbps(benchmark::State& state) {
380 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
381 "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_hevc_8Mbps.mp4",
382 false /* includeAudio */, true /* transcodeVideo */,
383 [mime = "video/hevc", bitrate = 8000000](AMediaFormat* dstFormat) {
384 SetMimeBitrate(dstFormat, mime, bitrate);
385 });
386}
387
388static void BM_1920x1080_Hevc17Mbps2Avc12Mbps(benchmark::State& state) {
389 TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4",
390 "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_h264_12Mbps.mp4",
391 false /* includeAudio */, true /* transcodeVideo */,
392 [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) {
393 SetMimeBitrate(dstFormat, mime, bitrate);
394 });
395}
396
397static void BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps(benchmark::State& state) {
398 TranscodeMediaFile(state, "tx_bm_1920_1080_60fps_hevc_28Mbps.mp4",
399 "tx_bm_1920_1080_60fps_hevc_28Mbps_transcoded_h264_15Mbps.mp4",
400 false /* includeAudio */, true /* transcodeVideo */,
401 [mime = "video/avc", bitrate = 15000000](AMediaFormat* dstFormat) {
402 SetMimeBitrate(dstFormat, mime, bitrate);
403 });
404}
405
406static void BM_1280x720_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
407 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
408 "tx_bm_1280_720_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
409 false /* includeAudio */, true /* transcodeVideo */,
410 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
411 SetMimeBitrate(dstFormat, mime, bitrate);
412 });
413}
414
415static void BM_1280x720_Avc10Mbps2AvcPassthrough(benchmark::State& state) {
416 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4",
417 "tx_bm_1280_720_30fps_h264_10Mbps_passthrough_V.mp4",
418 false /* includeAudio */, false /* transcodeVideo */);
419}
420
421static void BM_1280x720_Avc10MbpsAac2Avc4Mbps(benchmark::State& state) {
422 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
423 "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps.mp4",
424 false /* includeAudio */, true /* transcodeVideo */,
425 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
426 SetMimeBitrate(dstFormat, mime, bitrate);
427 });
428}
429
430static void BM_1280x720_Avc10MbpsAac2Avc4MbpsAac(benchmark::State& state) {
431 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
432 "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps_aac.mp4",
433 true /* includeAudio */, true /* transcodeVideo */,
434 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
435 SetMimeBitrate(dstFormat, mime, bitrate);
436 });
437}
438
439static void BM_1280x720_Avc10MbpsAac2AvcPassthrough(benchmark::State& state) {
440 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
441 "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_V.mp4",
442 false /* includeAudio */, false /* transcodeVideo */);
443}
444
445static void BM_1280x720_Avc10MbpsAac2AvcAacPassthrough(benchmark::State& state) {
446 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4",
447 "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_AV.mp4",
448 true /* includeAudio */, false /* transcodeVideo */);
449}
450
451static void BM_1280x720_Hevc8Mbps2Avc4Mbps(benchmark::State& state) {
452 TranscodeMediaFile(state, "tx_bm_1280_720_30fps_hevc_8Mbps.mp4",
453 "tx_bm_1280_720_30fps_hevc_8Mbps_transcoded_h264_4Mbps.mp4",
454 false /* includeAudio */, true /* transcodeVideo */,
455 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
456 SetMimeBitrate(dstFormat, mime, bitrate);
457 });
458}
459
460static void BM_1080x1920_Avc15Mbps2Avc8Mbps(benchmark::State& state) {
461 TranscodeMediaFile(state, "tx_bm_1080_1920_30fps_h264_15Mbps.mp4",
462 "tx_bm_1080_1920_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4",
463 false /* includeAudio */, true /* transcodeVideo */,
464 [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) {
465 SetMimeBitrate(dstFormat, mime, bitrate);
466 });
467}
468
469static void BM_720x1280_Avc10Mbps2Avc4Mbps(benchmark::State& state) {
470 TranscodeMediaFile(state, "tx_bm_720_1280_30fps_h264_10Mbps.mp4",
471 "tx_bm_720_1280_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4",
472 false /* includeAudio */, true /* transcodeVideo */,
473 [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) {
474 SetMimeBitrate(dstFormat, mime, bitrate);
475 });
476}
477
478static void BM_3840x2160_Hevc42Mbps2Avc20Mbps(benchmark::State& state) {
479 TranscodeMediaFile(state, "tx_bm_3840_2160_30fps_hevc_42Mbps.mp4",
480 "tx_bm_3840_2160_30fps_hevc_42Mbps_transcoded_h264_4Mbps.mp4",
481 false /* includeAudio */, true /* transcodeVideo */,
482 [mime = "video/avc", bitrate = 20000000](AMediaFormat* dstFormat) {
483 SetMimeBitrate(dstFormat, mime, bitrate);
484 });
485}
486
Linus Nilsson6bf46532020-10-07 11:58:02 -0700487//-------------------------------- Benchmark Registration ------------------------------------------
488
489// Benchmark registration wrapper for transcoding.
490#define TRANSCODER_BENCHMARK(func) \
491 BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)
492
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700493TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAudioVideo2AudioVideo);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700494TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcVideo2Video);
Linus Nilsson16d772b2020-09-29 19:21:11 -0700495TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AVMaxOperatingRate);
496TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcV2VMaxOperatingRate);
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700497TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720P);
498TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700499
500TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAudioVideo2AudioVideo);
501TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcVideo2Video);
502TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AVMaxOperatingRate);
503TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcV2VMaxOperatingRate);
Linus Nilssona7aa2f62020-10-29 13:19:35 -0700504TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720P);
505TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate);
Linus Nilsson6bf46532020-10-07 11:58:02 -0700506
Linus Nilsson6233fed2020-08-13 15:15:14 -0700507TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough);
508TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough);
Linus Nilsson8f0b8762020-07-23 17:12:45 -0700509
Naveen Kumar Ponnusamy82e14782020-12-16 10:50:43 -0800510TRANSCODER_BENCHMARK(BM_1920x1080_Avc22Mbps2Avc12Mbps);
511TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2Avc8Mbps);
512TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2AvcPassthrough);
513TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8Mbps);
514TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac);
515TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcPassthrough);
516TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough);
517TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Hevc8Mbps);
518TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Avc12Mbps);
519TRANSCODER_BENCHMARK(BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps);
520
521TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2Avc4Mbps);
522TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2AvcPassthrough);
523TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4Mbps);
524TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4MbpsAac);
525TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcPassthrough);
526TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcAacPassthrough);
527TRANSCODER_BENCHMARK(BM_1280x720_Hevc8Mbps2Avc4Mbps);
528
529TRANSCODER_BENCHMARK(BM_1080x1920_Avc15Mbps2Avc8Mbps);
530TRANSCODER_BENCHMARK(BM_720x1280_Avc10Mbps2Avc4Mbps);
531
532TRANSCODER_BENCHMARK(BM_3840x2160_Hevc42Mbps2Avc20Mbps);
533
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530534class CustomCsvReporter : public benchmark::BenchmarkReporter {
535public:
536 CustomCsvReporter() : mPrintedHeader(false) {}
537 virtual bool ReportContext(const Context& context);
538 virtual void ReportRuns(const std::vector<Run>& reports);
539
540private:
541 void PrintRunData(const Run& report);
542
543 bool mPrintedHeader;
544 std::vector<std::string> mHeaders = {"name", "real_time", "cpu_time", PARAM_VIDEO_FRAME_RATE};
545};
546
547bool CustomCsvReporter::ReportContext(const Context& context __unused) {
548 return true;
549}
550
551void CustomCsvReporter::ReportRuns(const std::vector<Run>& reports) {
552 std::ostream& Out = GetOutputStream();
553
554 if (!mPrintedHeader) {
555 // print the header
556 for (auto header = mHeaders.begin(); header != mHeaders.end();) {
557 Out << *header++;
558 if (header != mHeaders.end()) Out << ",";
559 }
560 Out << "\n";
561 mPrintedHeader = true;
562 }
563
564 // print results for each run
565 for (const auto& run : reports) {
566 PrintRunData(run);
567 }
568}
569
570void CustomCsvReporter::PrintRunData(const Run& run) {
571 if (run.error_occurred) {
572 return;
573 }
574 std::ostream& Out = GetOutputStream();
575 Out << run.benchmark_name() << ",";
576 Out << run.GetAdjustedRealTime() << ",";
577 Out << run.GetAdjustedCPUTime() << ",";
578 auto frameRate = run.counters.find(PARAM_VIDEO_FRAME_RATE);
579 if (frameRate == run.counters.end()) {
580 Out << "NA"
581 << ",";
582 } else {
583 Out << frameRate->second << ",";
584 }
585 Out << '\n';
586}
587
588int main(int argc, char** argv) {
Naveen Kumar Ponnusamy2d074ba2020-12-17 17:13:45 -0800589 android::ProcessState::self()->startThreadPool();
Naveen Kumar Ponnusamy8b8e7002020-12-02 12:01:32 +0530590 std::unique_ptr<benchmark::BenchmarkReporter> fileReporter;
591 for (int i = 1; i < argc; ++i) {
592 if (std::string(argv[i]).find("--benchmark_out") != std::string::npos) {
593 fileReporter.reset(new CustomCsvReporter);
594 break;
595 }
596 }
597 ::benchmark::Initialize(&argc, argv);
598 if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1;
599 ::benchmark::RunSpecifiedBenchmarks(nullptr, fileReporter.get());
600}