/* * Copyright (C) 2020 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /** * Native media transcoder library benchmark tests. * * How to run the benchmark: * * 1. Download the media assets from http://go/transcodingbenchmark and push the directory * ("TranscodingBenchmark") to /data/local/tmp. * * 2. Compile the benchmark and sync to device: * $ mm -j72 && adb sync * * 3. Run: * $ adb shell /data/nativetest64/MediaTranscoderBenchmark/MediaTranscoderBenchmark */ #include #include #include #include #include #include using namespace android; const std::string PARAM_VIDEO_FRAME_RATE = "VideoFrameRate"; class TranscoderCallbacks : public MediaTranscoder::CallbackInterface { public: virtual void onFinished(const MediaTranscoder* transcoder __unused) override { std::unique_lock lock(mMutex); mFinished = true; mCondition.notify_all(); } virtual void onError(const MediaTranscoder* transcoder __unused, media_status_t error) override { std::unique_lock lock(mMutex); mFinished = true; mStatus = error; mCondition.notify_all(); } virtual void onProgressUpdate(const MediaTranscoder* transcoder __unused, int32_t progress __unused) override {} virtual void onHeartBeat(const MediaTranscoder* transcoder __unused) override {} virtual void onCodecResourceLost(const MediaTranscoder* transcoder __unused, const std::shared_ptr& pausedState __unused) override {} bool waitForTranscodingFinished() { std::unique_lock lock(mMutex); while (!mFinished) { if (mCondition.wait_for(lock, std::chrono::minutes(5)) == std::cv_status::timeout) { return false; } } return true; } media_status_t mStatus = AMEDIA_OK; private: std::mutex mMutex; std::condition_variable mCondition; bool mFinished = false; }; static AMediaFormat* CreateDefaultVideoFormat() { // Default bitrate static constexpr int32_t kVideoBitRate = 20 * 1000 * 1000; // 20Mbs AMediaFormat* videoFormat = AMediaFormat_new(); AMediaFormat_setInt32(videoFormat, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate); AMediaFormat_setString(videoFormat, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC); return videoFormat; } /** * Callback to configure tracks for transcoding. * @param mime The source track mime type. * @param dstFormat The destination format if the track should be transcoded or nullptr if the track * should be passed through. * @return True if the track should be included in the output file. */ using TrackSelectionCallback = std::function; static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName, const std::string& dstFileName, TrackSelectionCallback trackSelectionCallback) { // Write-only, create file if non-existent. static constexpr int kDstOpenFlags = O_WRONLY | O_CREAT; // User R+W permission. static constexpr int kDstFileMode = S_IRUSR | S_IWUSR; // Asset directory static const std::string kAssetDirectory = "/data/local/tmp/TranscodingBenchmark/"; // Transcoding configuration params to be logged int64_t trackDurationUs = 0; int32_t width = 0; int32_t height = 0; std::string sourceMime = "NA"; std::string targetMime = "NA"; bool includeAudio = false; bool transcodeVideo = false; int32_t targetBitrate = 0; int srcFd = 0; int dstFd = 0; std::string srcPath = kAssetDirectory + srcFileName; std::string dstPath = kAssetDirectory + dstFileName; media_status_t status = AMEDIA_OK; if ((srcFd = open(srcPath.c_str(), O_RDONLY)) < 0) { state.SkipWithError("Unable to open source file"); goto exit; } if ((dstFd = open(dstPath.c_str(), kDstOpenFlags, kDstFileMode)) < 0) { state.SkipWithError("Unable to open destination file"); goto exit; } for (auto _ : state) { auto callbacks = std::make_shared(); auto transcoder = MediaTranscoder::create(callbacks); status = transcoder->configureSource(srcFd); if (status != AMEDIA_OK) { state.SkipWithError("Unable to configure transcoder source"); goto exit; } status = transcoder->configureDestination(dstFd); if (status != AMEDIA_OK) { state.SkipWithError("Unable to configure transcoder destination"); goto exit; } std::vector> trackFormats = transcoder->getTrackFormats(); for (int i = 0; i < trackFormats.size(); ++i) { AMediaFormat* srcFormat = trackFormats[i].get(); AMediaFormat* dstFormat = nullptr; const char* mime = nullptr; if (!AMediaFormat_getString(srcFormat, AMEDIAFORMAT_KEY_MIME, &mime)) { state.SkipWithError("Source track format does not have MIME type"); goto exit; } if (strncmp(mime, "video/", 6) == 0) { int32_t frameCount; if (AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_FRAME_COUNT, &frameCount)) { state.counters[PARAM_VIDEO_FRAME_RATE] = benchmark::Counter( frameCount, benchmark::Counter::kIsIterationInvariantRate); } if (!AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_WIDTH, &width)) { state.SkipWithError("Video source track format does not have width"); goto exit; } if (!AMediaFormat_getInt32(srcFormat, AMEDIAFORMAT_KEY_HEIGHT, &height)) { state.SkipWithError("Video source track format does not have height"); goto exit; } AMediaFormat_getInt64(srcFormat, AMEDIAFORMAT_KEY_DURATION, &trackDurationUs); sourceMime = mime; } if (trackSelectionCallback(mime, &dstFormat)) { status = transcoder->configureTrackFormat(i, dstFormat); if (strncmp(mime, "video/", 6) == 0 && dstFormat != nullptr) { const char* mime = nullptr; if (AMediaFormat_getString(dstFormat, AMEDIAFORMAT_KEY_MIME, &mime)) { targetMime = mime; } AMediaFormat_getInt32(dstFormat, AMEDIAFORMAT_KEY_BIT_RATE, &targetBitrate); transcodeVideo = true; } else if (strncmp(mime, "audio/", 6) == 0) { includeAudio = true; } } if (dstFormat != nullptr) { AMediaFormat_delete(dstFormat); } if (status != AMEDIA_OK) { state.SkipWithError("Unable to configure track"); goto exit; } } status = transcoder->start(); if (status != AMEDIA_OK) { state.SkipWithError("Unable to start transcoder"); goto exit; } if (!callbacks->waitForTranscodingFinished()) { transcoder->cancel(); state.SkipWithError("Transcoder timed out"); goto exit; } if (callbacks->mStatus != AMEDIA_OK) { state.SkipWithError("Transcoder error when running"); goto exit; } } // Set transcoding configuration params in benchmark label state.SetLabel(srcFileName + "," + std::to_string(width) + "x" + std::to_string(height) + "," + sourceMime + "," + std::to_string(trackDurationUs/1000) + "," + (includeAudio ? "Yes" : "No") + "," + (transcodeVideo ? "Yes" : "No") + "," + targetMime + "," + std::to_string(targetBitrate) ); exit: if (srcFd > 0) close(srcFd); if (dstFd > 0) close(dstFd); } /** * Callback to edit track format for transcoding. * @param dstFormat The default track format for the track type. */ using TrackFormatEditCallback = std::function; static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName, const std::string& dstFileName, bool includeAudio, bool transcodeVideo, const TrackFormatEditCallback& videoFormatEditor = nullptr) { TranscodeMediaFile(state, srcFileName, dstFileName, [=](const char* mime, AMediaFormat** dstFormatOut) -> bool { *dstFormatOut = nullptr; if (strncmp(mime, "video/", 6) == 0 && transcodeVideo) { *dstFormatOut = CreateDefaultVideoFormat(); if (videoFormatEditor != nullptr) { videoFormatEditor(*dstFormatOut); } } else if (strncmp(mime, "audio/", 6) == 0 && !includeAudio) { return false; } return true; }); } static void SetMaxOperatingRate(AMediaFormat* format) { AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1); } //-------------------------------- AVC to AVC Benchmarks ------------------------------------------- static void BM_TranscodeAvc2AvcAudioVideo2AudioVideo(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4", "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */); } static void BM_TranscodeAvc2AvcVideo2Video(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4", "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4", false /* includeAudio */, true /* transcodeVideo */); } static void BM_TranscodeAvc2AvcAV2AVMaxOperatingRate(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4", "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate); } static void BM_TranscodeAvc2AvcV2VMaxOperatingRate(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4", "video_1920x1080_3648frame_h264_22Mbps_30fps_transcoded_V.mp4", false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate); } static void BM_TranscodeAvc2AvcAV2AV720P(benchmark::State& state) { TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4", "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */); } static void BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) { TranscodeMediaFile(state, "video_1280x720_3648frame_h264_16Mbps_30fps_aac.mp4", "video_1280x720_3648frame_h264_16Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate); } //-------------------------------- HEVC to AVC Benchmarks ------------------------------------------ static void BM_TranscodeHevc2AvcAudioVideo2AudioVideo(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4", "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */); } static void BM_TranscodeHevc2AvcVideo2Video(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4", "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4", false /* includeAudio */, true /* transcodeVideo */); } static void BM_TranscodeHevc2AvcAV2AVMaxOperatingRate(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4", "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate); } static void BM_TranscodeHevc2AvcV2VMaxOperatingRate(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3863frame_hevc_4Mbps_30fps.mp4", "video_1920x1080_3863frame_hevc_4Mbps_30fps_transcoded_V.mp4", false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate); } static void BM_TranscodeHevc2AvcAV2AV720P(benchmark::State& state) { TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4", "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */); } static void BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate(benchmark::State& state) { TranscodeMediaFile(state, "video_1280x720_3863frame_hevc_16Mbps_30fps_aac.mp4", "video_1280x720_3863frame_hevc_16Mbps_30fps_aac_transcoded_AV.mp4", true /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate); } //-------------------------------- Passthrough Benchmarks ------------------------------------------ static void BM_TranscodeAudioVideoPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4", "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_passthrough_AV.mp4", true /* includeAudio */, false /* transcodeVideo */); } static void BM_TranscodeVideoPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps.mp4", "video_1920x1080_3648frame_h264_22Mbps_30fps_passthrough_AV.mp4", false /* includeAudio */, false /* transcodeVideo */); } //---------------------------- Codecs, Resolutions, Bitrate --------------------------------------- static void SetMimeBitrate(AMediaFormat* format, std::string mime, int32_t bitrate) { AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, mime.c_str()); AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, bitrate); } static void BM_1920x1080_Avc22Mbps2Avc12Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_22Mbps.mp4", "tx_bm_1920_1080_30fps_h264_22Mbps_transcoded_h264_12Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1920x1080_Avc15Mbps2Avc8Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4", "tx_bm_1920_1080_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1920x1080_Avc15Mbps2AvcPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps.mp4", "tx_bm_1920_1080_30fps_h264_15Mbps_passthrough_V.mp4", false /* includeAudio */, false /* transcodeVideo */); } static void BM_1920x1080_Avc15MbpsAac2Avc8Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4", "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4", "tx_bm_1920_1080_30fps_h264_15Mbps_aac_transcoded_h264_8Mbps_aac.mp4", true /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1920x1080_Avc15MbpsAac2AvcPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4", "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_V.mp4", false /* includeAudio */, false /* transcodeVideo */); } static void BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_h264_15Mbps_aac.mp4", "tx_bm_1920_1080_30fps_h264_15Mbps_aac_passthrough_AV.mp4", true /* includeAudio */, false /* transcodeVideo */); } static void BM_1920x1080_Hevc17Mbps2Hevc8Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4", "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_hevc_8Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/hevc", bitrate = 8000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1920x1080_Hevc17Mbps2Avc12Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_30fps_hevc_17Mbps.mp4", "tx_bm_1920_1080_30fps_hevc_17Mbps_transcoded_h264_12Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 12000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1920_1080_60fps_hevc_28Mbps.mp4", "tx_bm_1920_1080_60fps_hevc_28Mbps_transcoded_h264_15Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 15000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1280x720_Avc10Mbps2Avc4Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4", "tx_bm_1280_720_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1280x720_Avc10Mbps2AvcPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps.mp4", "tx_bm_1280_720_30fps_h264_10Mbps_passthrough_V.mp4", false /* includeAudio */, false /* transcodeVideo */); } static void BM_1280x720_Avc10MbpsAac2Avc4Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4", "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1280x720_Avc10MbpsAac2Avc4MbpsAac(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4", "tx_bm_1280_720_30fps_h264_10Mbps_aac_transcoded_h264_4Mbps_aac.mp4", true /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1280x720_Avc10MbpsAac2AvcPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4", "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_V.mp4", false /* includeAudio */, false /* transcodeVideo */); } static void BM_1280x720_Avc10MbpsAac2AvcAacPassthrough(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_h264_10Mbps_aac.mp4", "tx_bm_1280_720_30fps_h264_10Mbps_aac_passthrough_AV.mp4", true /* includeAudio */, false /* transcodeVideo */); } static void BM_1280x720_Hevc8Mbps2Avc4Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1280_720_30fps_hevc_8Mbps.mp4", "tx_bm_1280_720_30fps_hevc_8Mbps_transcoded_h264_4Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_1080x1920_Avc15Mbps2Avc8Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_1080_1920_30fps_h264_15Mbps.mp4", "tx_bm_1080_1920_30fps_h264_15Mbps_transcoded_h264_8Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 8000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_720x1280_Avc10Mbps2Avc4Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_720_1280_30fps_h264_10Mbps.mp4", "tx_bm_720_1280_30fps_h264_10Mbps_transcoded_h264_4Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 4000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } static void BM_3840x2160_Hevc42Mbps2Avc20Mbps(benchmark::State& state) { TranscodeMediaFile(state, "tx_bm_3840_2160_30fps_hevc_42Mbps.mp4", "tx_bm_3840_2160_30fps_hevc_42Mbps_transcoded_h264_4Mbps.mp4", false /* includeAudio */, true /* transcodeVideo */, [mime = "video/avc", bitrate = 20000000](AMediaFormat* dstFormat) { SetMimeBitrate(dstFormat, mime, bitrate); }); } //-------------------------------- Benchmark Registration ------------------------------------------ // Benchmark registration wrapper for transcoding. #define TRANSCODER_BENCHMARK(func) \ BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond) TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAudioVideo2AudioVideo); TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcVideo2Video); TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AVMaxOperatingRate); TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcV2VMaxOperatingRate); TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720P); TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AV720PMaxOperatingRate); TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAudioVideo2AudioVideo); TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcVideo2Video); TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AVMaxOperatingRate); TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcV2VMaxOperatingRate); TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720P); TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AV720PMaxOperatingRate); TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough); TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough); TRANSCODER_BENCHMARK(BM_1920x1080_Avc22Mbps2Avc12Mbps); TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2Avc8Mbps); TRANSCODER_BENCHMARK(BM_1920x1080_Avc15Mbps2AvcPassthrough); TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8Mbps); TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2Avc8MbpsAac); TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcPassthrough); TRANSCODER_BENCHMARK(BM_1920x1080_Avc15MbpsAac2AvcAacPassthrough); TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Hevc8Mbps); TRANSCODER_BENCHMARK(BM_1920x1080_Hevc17Mbps2Avc12Mbps); TRANSCODER_BENCHMARK(BM_1920x1080_60fps_Hevc28Mbps2Avc15Mbps); TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2Avc4Mbps); TRANSCODER_BENCHMARK(BM_1280x720_Avc10Mbps2AvcPassthrough); TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4Mbps); TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2Avc4MbpsAac); TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcPassthrough); TRANSCODER_BENCHMARK(BM_1280x720_Avc10MbpsAac2AvcAacPassthrough); TRANSCODER_BENCHMARK(BM_1280x720_Hevc8Mbps2Avc4Mbps); TRANSCODER_BENCHMARK(BM_1080x1920_Avc15Mbps2Avc8Mbps); TRANSCODER_BENCHMARK(BM_720x1280_Avc10Mbps2Avc4Mbps); TRANSCODER_BENCHMARK(BM_3840x2160_Hevc42Mbps2Avc20Mbps); class CustomCsvReporter : public benchmark::BenchmarkReporter { public: CustomCsvReporter() : mPrintedHeader(false) {} virtual bool ReportContext(const Context& context); virtual void ReportRuns(const std::vector& reports); private: void PrintRunData(const Run& report); bool mPrintedHeader; std::vector mHeaders = { "File", "Resolution", "SourceMime", "VideoTrackDuration(ms)", "IncludeAudio", "TranscodeVideo", "TargetMime", "TargetBirate(bps)", "real_time(ms)", "cpu_time(ms)", PARAM_VIDEO_FRAME_RATE }; }; bool CustomCsvReporter::ReportContext(const Context& context __unused) { return true; } void CustomCsvReporter::ReportRuns(const std::vector& reports) { std::ostream& Out = GetOutputStream(); if (!mPrintedHeader) { // print the header for (auto header = mHeaders.begin(); header != mHeaders.end();) { Out << *header++; if (header != mHeaders.end()) Out << ","; } Out << "\n"; mPrintedHeader = true; } // print results for each run for (const auto& run : reports) { PrintRunData(run); } } void CustomCsvReporter::PrintRunData(const Run& run) { if (run.error_occurred) { return; } std::ostream& Out = GetOutputStream(); // Log the transcoding params reported through label Out << run.report_label << ","; Out << run.GetAdjustedRealTime() << ","; Out << run.GetAdjustedCPUTime() << ","; auto frameRate = run.counters.find(PARAM_VIDEO_FRAME_RATE); if (frameRate == run.counters.end()) { Out << "NA" << ","; } else { Out << frameRate->second << ","; } Out << '\n'; } int main(int argc, char** argv) { android::ProcessState::self()->startThreadPool(); std::unique_ptr fileReporter; for (int i = 1; i < argc; ++i) { if (std::string(argv[i]).find("--benchmark_out") != std::string::npos) { fileReporter.reset(new CustomCsvReporter); break; } } ::benchmark::Initialize(&argc, argv); if (::benchmark::ReportUnrecognizedArguments(argc, argv)) return 1; ::benchmark::RunSpecifiedBenchmarks(nullptr, fileReporter.get()); }