From cd83ae2d6555ab19458820c04c5ce3a3714b1233 Mon Sep 17 00:00:00 2001 From: Steve Anton Date: Thu, 8 Apr 2021 11:26:04 -0700 Subject: [PATCH] Speed up FrameCombiner::Combine by 3x MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There were a couple operations in the mixer which touched AudioFrame data() and mutable_data() getters in a hot loop. These getters have a if (muted) conditional in them which led to inefficient code generation and execution. Profiled using Google Meet with 6 audio-only speaking participants. Meet uses 3 audio receive streams. Before: https://pprof.corp.google.com/user-profile?id=02526c98ca1f60ba7b340b2f5dabb72a&tab=flame&path=18l9q740udb80g1iq9r1c1gv6b9k1cuuq200eztpq0054kuq0 After: https://pprof.corp.google.com/user-profile?id=32a33e5c90c650e013bdf5008d9b5fd3&tab=flame&path=18l9q740udb80g1iq9r1c1gv6b9k1cuuq200eztpq0054kuq0 (Zoomed in on the audio render thread.) Bug: webrtc:12662 Change-Id: If6ecb5de02095b8b0e4938f1a1817b55d388e01a Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/214560 Reviewed-by: Per Ã…hgren Reviewed-by: Olga Sharonova Reviewed-by: Alex Loiko Commit-Queue: Steve Anton Cr-Commit-Position: refs/heads/master@{#33712} --- audio/utility/audio_frame_operations.cc | 4 ++-- modules/audio_mixer/frame_combiner.cc | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/audio/utility/audio_frame_operations.cc b/audio/utility/audio_frame_operations.cc index a9d2cf1632..e13a09bace 100644 --- a/audio/utility/audio_frame_operations.cc +++ b/audio/utility/audio_frame_operations.cc @@ -169,10 +169,10 @@ void AudioFrameOperations::UpmixChannels(size_t target_number_of_channels, if (!frame->muted()) { // Up-mixing done in place. Going backwards through the frame ensure nothing // is irrevocably overwritten. + int16_t* frame_data = frame->mutable_data(); for (int i = frame->samples_per_channel_ - 1; i >= 0; i--) { for (size_t j = 0; j < target_number_of_channels; ++j) { - frame->mutable_data()[target_number_of_channels * i + j] = - frame->data()[i]; + frame_data[target_number_of_channels * i + j] = frame_data[i]; } } } diff --git a/modules/audio_mixer/frame_combiner.cc b/modules/audio_mixer/frame_combiner.cc index e184506b4c..fb6f72af75 100644 --- a/modules/audio_mixer/frame_combiner.cc +++ b/modules/audio_mixer/frame_combiner.cc @@ -88,13 +88,14 @@ void MixToFloatFrame(rtc::ArrayView mix_list, // Convert to FloatS16 and mix. for (size_t i = 0; i < mix_list.size(); ++i) { const AudioFrame* const frame = mix_list[i]; + const int16_t* const frame_data = frame->data(); for (size_t j = 0; j < std::min(number_of_channels, FrameCombiner::kMaximumNumberOfChannels); ++j) { for (size_t k = 0; k < std::min(samples_per_channel, FrameCombiner::kMaximumChannelSize); ++k) { - (*mixing_buffer)[j][k] += frame->data()[number_of_channels * k + j]; + (*mixing_buffer)[j][k] += frame_data[number_of_channels * k + j]; } } } @@ -113,10 +114,11 @@ void InterleaveToAudioFrame(AudioFrameView mixing_buffer_view, AudioFrame* audio_frame_for_mixing) { const size_t number_of_channels = mixing_buffer_view.num_channels(); const size_t samples_per_channel = mixing_buffer_view.samples_per_channel(); + int16_t* const mixing_data = audio_frame_for_mixing->mutable_data(); // Put data in the result frame. for (size_t i = 0; i < number_of_channels; ++i) { for (size_t j = 0; j < samples_per_channel; ++j) { - audio_frame_for_mixing->mutable_data()[number_of_channels * j + i] = + mixing_data[number_of_channels * j + i] = FloatS16ToS16(mixing_buffer_view.channel(i)[j]); } }