Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6bf46534 authored by Linus Nilsson's avatar Linus Nilsson
Browse files

Transcoder: Benchmark HEVC->AVC and max operating rate

Test HEVC and max operating rate on both media trasncoder
and track transcoder level.

Fixes: 170322594
Test: Run benchmark
Change-Id: I4bb79ea0199a1172b89b5f2a5c73af29e6f83cad
parent 8a96cfc8
Loading
Loading
Loading
Loading
+58 −12
Original line number Diff line number Diff line
@@ -216,7 +216,8 @@ private:
};

static std::shared_ptr<AMediaFormat> GetDefaultTrackFormat(MediaType mediaType,
                                                           AMediaFormat* sourceFormat) {
                                                           AMediaFormat* sourceFormat,
                                                           bool maxOperatingRate) {
    // Default video config.
    static constexpr int32_t kVideoBitRate = 20 * 1000 * 1000;  // 20 mbps
    static constexpr float kVideoFrameRate = 30.0f;             // 30 fps
@@ -229,6 +230,11 @@ static std::shared_ptr<AMediaFormat> GetDefaultTrackFormat(MediaType mediaType,
        AMediaFormat_setString(format, AMEDIAFORMAT_KEY_MIME, AMEDIA_MIMETYPE_VIDEO_AVC);
        AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_BIT_RATE, kVideoBitRate);
        AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_FRAME_RATE, kVideoFrameRate);

        if (maxOperatingRate) {
            AMediaFormat_setFloat(format, AMEDIAFORMAT_KEY_OPERATING_RATE, INT32_MAX);
            AMediaFormat_setInt32(format, AMEDIAFORMAT_KEY_PRIORITY, 1);
        }
    }
    // nothing for audio.

@@ -282,7 +288,7 @@ static void ConfigureEmptySampleConsumer(const std::shared_ptr<MediaTrackTransco
 */
static bool ConfigureSampleReader(const std::shared_ptr<MediaTrackTranscoder>& transcoder,
                                  const std::shared_ptr<MediaSampleReader>& sampleReader,
                                  MediaType mediaType) {
                                  MediaType mediaType, bool maxOperatingRate) {
    int srcTrackIndex = -1;
    std::shared_ptr<AMediaFormat> srcTrackFormat = nullptr;

@@ -312,7 +318,8 @@ static bool ConfigureSampleReader(const std::shared_ptr<MediaTrackTranscoder>& t
        return false;
    }

    auto destinationFormat = GetDefaultTrackFormat(mediaType, srcTrackFormat.get());
    auto destinationFormat =
            GetDefaultTrackFormat(mediaType, srcTrackFormat.get(), maxOperatingRate);
    status = transcoder->configure(sampleReader, srcTrackIndex, destinationFormat);
    if (status != AMEDIA_OK) {
        LOG(ERROR) << "transcoder configure returned " << status;
@@ -323,7 +330,7 @@ static bool ConfigureSampleReader(const std::shared_ptr<MediaTrackTranscoder>& t
}

static void BenchmarkTranscoder(benchmark::State& state, const std::string& srcFileName,
                                bool mockReader, MediaType mediaType) {
                                bool mockReader, MediaType mediaType, bool maxOperatingRate) {
    for (auto _ : state) {
        std::shared_ptr<TrackTranscoderCallbacks> callbacks =
                std::make_shared<TrackTranscoderCallbacks>();
@@ -341,7 +348,7 @@ static void BenchmarkTranscoder(benchmark::State& state, const std::string& srcF
            return;
        }

        if (!ConfigureSampleReader(transcoder, sampleReader, mediaType)) {
        if (!ConfigureSampleReader(transcoder, sampleReader, mediaType, maxOperatingRate)) {
            state.SkipWithError("Unable to configure the transcoder");
            return;
        }
@@ -367,33 +374,72 @@ static void BenchmarkTranscoder(benchmark::State& state, const std::string& srcF
    }
}

// Benchmark registration wrapper for transcoding.
#define TRANSCODER_BENCHMARK(func) \
    BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)
//-------------------------------- AVC to AVC Benchmarks -------------------------------------------

static void BM_VideoTranscode_AVC2AVC_NoMuxer(benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, false /* mockReader */, kVideo);
    BenchmarkTranscoder(state, srcFile, false /* mockReader */, kVideo,
                        false /* maxOperatingRate */);
}

static void BM_VideoTranscode_AVC2AVC_NoMuxer_NoExtractor(benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, true /* mockReader */, kVideo);
    BenchmarkTranscoder(state, srcFile, true /* mockReader */, kVideo,
                        false /* maxOperatingRate */);
}

static void BM_VideoTranscode_AVC2AVC_NoMuxer_MaxOperatingRate(benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, false /* mockReader */, kVideo,
                        true /* maxOperatingRate */);
}

static void BM_VideoTranscode_AVC2AVC_NoMuxer_NoExtractor_MaxOperatingRate(
        benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, true /* mockReader */, kVideo, true /* maxOperatingRate */);
}

//-------------------------------- HEVC to AVC Benchmarks ------------------------------------------

static void BM_VideoTranscode_HEVC2AVC_NoMuxer(benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, false /* mockReader */, kVideo);
    BenchmarkTranscoder(state, srcFile, false /* mockReader */, kVideo,
                        false /* maxOperatingRate */);
}

static void BM_VideoTranscode_HEVC2AVC_NoMuxer_NoExtractor(benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, true /* mockReader */, kVideo);
    BenchmarkTranscoder(state, srcFile, true /* mockReader */, kVideo,
                        false /* maxOperatingRate */);
}

static void BM_VideoTranscode_HEVC2AVC_NoMuxer_MaxOperatingRate(benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, false /* mockReader */, kVideo,
                        true /* maxOperatingRate */);
}

static void BM_VideoTranscode_HEVC2AVC_NoMuxer_NoExtractor_MaxOperatingRate(
        benchmark::State& state) {
    const char* srcFile = "video_1920x1080_3863frame_hevc_4Mbps_30fps_aac.mp4";
    BenchmarkTranscoder(state, srcFile, true /* mockReader */, kVideo, true /* maxOperatingRate */);
}

//-------------------------------- Benchmark Registration ------------------------------------------

// Benchmark registration wrapper for transcoding.
#define TRANSCODER_BENCHMARK(func) \
    BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)

TRANSCODER_BENCHMARK(BM_VideoTranscode_AVC2AVC_NoMuxer);
TRANSCODER_BENCHMARK(BM_VideoTranscode_AVC2AVC_NoMuxer_NoExtractor);
TRANSCODER_BENCHMARK(BM_VideoTranscode_AVC2AVC_NoMuxer_MaxOperatingRate);
TRANSCODER_BENCHMARK(BM_VideoTranscode_AVC2AVC_NoMuxer_NoExtractor_MaxOperatingRate);

TRANSCODER_BENCHMARK(BM_VideoTranscode_HEVC2AVC_NoMuxer);
TRANSCODER_BENCHMARK(BM_VideoTranscode_HEVC2AVC_NoMuxer_NoExtractor);
TRANSCODER_BENCHMARK(BM_VideoTranscode_HEVC2AVC_NoMuxer_MaxOperatingRate);
TRANSCODER_BENCHMARK(BM_VideoTranscode_HEVC2AVC_NoMuxer_NoExtractor_MaxOperatingRate);

BENCHMARK_MAIN();
+59 −33
Original line number Diff line number Diff line
@@ -191,14 +191,24 @@ exit:
    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<void(AMediaFormat* dstFormat)>;

static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFileName,
                               const std::string& dstFileName, bool includeAudio,
                               bool transcodeVideo) {
                               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;
                           }
@@ -206,9 +216,12 @@ static void TranscodeMediaFile(benchmark::State& state, const std::string& srcFi
                       });
}

// Benchmark registration wrapper for transcoding.
#define TRANSCODER_BENCHMARK(func) \
    BENCHMARK(func)->UseRealTime()->MeasureProcessCPUTime()->Unit(benchmark::kMillisecond)
static void SetMaxOperatingRate(AMediaFormat* format) {
    AMediaFormat_setFloat(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",
@@ -216,12 +229,6 @@ static void BM_TranscodeAvc2AvcAudioVideo2AudioVideo(benchmark::State& state) {
                       true /* includeAudio */, true /* transcodeVideo */);
}

static void BM_TranscodeAvc2AvcAudioVideo2Video(benchmark::State& state) {
    TranscodeMediaFile(state, "video_1920x1080_3648frame_h264_22Mbps_30fps_aac.mp4",
                       "video_1920x1080_3648frame_h264_22Mbps_30fps_aac_transcoded_V.mp4",
                       false /* 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",
@@ -231,35 +238,43 @@ static void BM_TranscodeAvc2AvcVideo2Video(benchmark::State& state) {
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",
                       [](const char* mime, AMediaFormat** dstFormatOut) -> bool {
                           AMediaFormat* dstFormat = nullptr;
                           if (strncmp(mime, "video/", 6) == 0) {
                               dstFormat = CreateDefaultVideoFormat();
                               AMediaFormat_setFloat(dstFormat, AMEDIAFORMAT_KEY_OPERATING_RATE,
                                                     INT32_MAX);
                               AMediaFormat_setInt32(dstFormat, AMEDIAFORMAT_KEY_PRIORITY, 1);
                           }
                           *dstFormatOut = dstFormat;
                           return true;
                       });
                       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",
                       [](const char* mime, AMediaFormat** dstFormatOut) -> bool {
                           if (strncmp(mime, "video/", 6) == 0) {
                               AMediaFormat* dstFormat = CreateDefaultVideoFormat();
                               AMediaFormat_setFloat(dstFormat, AMEDIAFORMAT_KEY_OPERATING_RATE,
                                                     INT32_MAX);
                               AMediaFormat_setInt32(dstFormat, AMEDIAFORMAT_KEY_PRIORITY, 1);
                               *dstFormatOut = dstFormat;
                               return true;
                       false /* includeAudio */, true /* transcodeVideo */, SetMaxOperatingRate);
}
                           return false;
                       });

//-------------------------------- 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);
}

//-------------------------------- 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",
@@ -271,11 +286,22 @@ static void BM_TranscodeVideoPassthrough(benchmark::State& state) {
                       false /* includeAudio */, false /* transcodeVideo */);
}

//-------------------------------- 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_TranscodeAvc2AvcAudioVideo2Video);
TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcVideo2Video);
TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcAV2AVMaxOperatingRate);
TRANSCODER_BENCHMARK(BM_TranscodeAvc2AvcV2VMaxOperatingRate);

TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAudioVideo2AudioVideo);
TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcVideo2Video);
TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcAV2AVMaxOperatingRate);
TRANSCODER_BENCHMARK(BM_TranscodeHevc2AvcV2VMaxOperatingRate);

TRANSCODER_BENCHMARK(BM_TranscodeAudioVideoPassthrough);
TRANSCODER_BENCHMARK(BM_TranscodeVideoPassthrough);