blob: a651fa2865b8f687d8a7a8658de850212c78eefd [file] [log] [blame]
Linus Nilsson6c103702020-08-11 15:13:13 -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 * MediaSampleReader 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/MediaSampleReaderBenchmark/MediaSampleReaderBenchmark
30 */
31
32#define LOG_TAG "MediaSampleReaderBenchmark"
33
34#include <android-base/logging.h>
35#include <benchmark/benchmark.h>
36#include <fcntl.h>
37#include <media/MediaSampleReaderNDK.h>
38#include <unistd.h>
39
40#include <thread>
41
42using namespace android;
43
44static void ReadMediaSamples(benchmark::State& state, const std::string& srcFileName,
45 bool readAudio) {
46 // Asset directory
47 static const std::string kAssetDirectory = "/data/local/tmp/TranscodingBenchmark/";
48
49 int srcFd = 0;
50 std::string srcPath = kAssetDirectory + srcFileName;
51
52 if ((srcFd = open(srcPath.c_str(), O_RDONLY)) < 0) {
53 state.SkipWithError("Unable to open source file");
54 return;
55 }
56
57 const size_t fileSize = lseek(srcFd, 0, SEEK_END);
58 lseek(srcFd, 0, SEEK_SET);
59
60 for (auto _ : state) {
61 auto sampleReader = MediaSampleReaderNDK::createFromFd(srcFd, 0, fileSize);
62
63 std::vector<std::thread> trackThreads;
64
65 for (int trackIndex = 0; trackIndex < sampleReader->getTrackCount(); ++trackIndex) {
66 const char* mime = nullptr;
67
68 AMediaFormat* trackFormat = sampleReader->getTrackFormat(trackIndex);
69 AMediaFormat_getString(trackFormat, AMEDIAFORMAT_KEY_MIME, &mime);
70
71 if (strncmp(mime, "video/", 6) == 0) {
72 int32_t frameCount;
73 if (AMediaFormat_getInt32(trackFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) {
74 state.counters["VideoFrameRate"] =
75 benchmark::Counter(frameCount, benchmark::Counter::kIsRate);
76 }
77 } else if (!readAudio && strncmp(mime, "audio/", 6) == 0) {
78 continue;
79 }
80
81 trackThreads.emplace_back([trackIndex, sampleReader, &state] {
82 LOG(INFO) << "Track " << trackIndex << " started";
83 MediaSampleInfo info;
84
85 size_t bufferSize = 0;
86 std::unique_ptr<uint8_t[]> buffer;
87
88 while (true) {
89 media_status_t status = sampleReader->getSampleInfoForTrack(trackIndex, &info);
90 if (status == AMEDIA_ERROR_END_OF_STREAM) {
91 break;
92 }
93
94 if (info.size > bufferSize) {
95 bufferSize = info.size;
96 buffer.reset(new uint8_t[bufferSize]);
97 }
98
99 status = sampleReader->readSampleDataForTrack(trackIndex, buffer.get(),
100 bufferSize);
101 if (status != AMEDIA_OK) {
102 state.SkipWithError("Error reading sample data");
103 break;
104 }
105
106 sampleReader->advanceTrack(trackIndex);
107 }
108
109 LOG(INFO) << "Track " << trackIndex << " finished";
110 });
111 }
112
113 for (auto& thread : trackThreads) {
114 thread.join();
115 }
116 }
117
118 close(srcFd);
119}
120
121// Benchmark registration wrapper for transcoding.
122#define TRANSCODER_BENCHMARK(func) \
123 BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)
124
125static void BM_MediaSampleReader_AudioVideo(benchmark::State& state) {
126 ReadMediaSamples(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
127 true /* readAudio */);
128}
129
130static void BM_MediaSampleReader_Video(benchmark::State& state) {
131 ReadMediaSamples(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
132 false /* readAudio */);
133}
134
135TRANSCODER_BENCHMARK(BM_MediaSampleReader_AudioVideo);
136TRANSCODER_BENCHMARK(BM_MediaSampleReader_Video);
137
138BENCHMARK_MAIN();