Speed up FrameCombiner::Combine by 3x

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 <peah@webrtc.org>
Reviewed-by: Olga Sharonova <olka@webrtc.org>
Reviewed-by: Alex Loiko <aleloi@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#33712}
This commit is contained in:
Steve Anton 2021-04-08 11:26:04 -07:00 committed by Commit Bot
parent 32347b50ba
commit cd83ae2d65
2 changed files with 6 additions and 4 deletions

View File

@ -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];
}
}
}

View File

@ -88,13 +88,14 @@ void MixToFloatFrame(rtc::ArrayView<const AudioFrame* const> 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<const float> 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]);
}
}