Expose WebRTC's audio_mixer#806
Conversation
b0d1171 to
2a8cb8e
Compare
|
@xianshijing-lk This is an older PR that Zed has been using downstream for a while. I rebased it and ran clang-format on the C++ code. It would be great to get this merged. |
| } | ||
| } | ||
|
|
||
| pub trait AudioMixerSource { |
There was a problem hiding this comment.
How is the thread safety for the audio mixer ?
I feel like they are not safe but my limited rust knowledge is not enough to get deep into it.
@ladvoc, could you please help review the code and look at the thread safety ?
There was a problem hiding this comment.
Great question. I merely rebased this code and did not write it, so I was not very familiar before you asked. The thread safety of livekit::AudioMixer on the C++ side is not good. livekit::AudioMixer stores its own std::vector<std::shared_ptr<AudioMixerSource>> sources_ member. I don't see the reason for this. libwebrtc's webrtc::AudioMixerImpl stores its own list of sources internally which are guarded by a mutex. So livekit::AudioMixer seems to add a redundant list on top of that but without the thread safety, despite the manual impl's for Send + Sync traits.
This seems to not have been a practical issue for Zed because Zed wraps its AudioMixer with Arc<Mutex> on the Rust side. However, just looking at the Rust API exposed by the libwebrtc crate here, there is no reason for anyone who didn't write this code to suspect that Arc<Mutex> is necessary without documentation. There are also no SAFETY comments in the higher level Rust wrappers in the libwebrtc crate for the unsafe blocks documenting why it is safe to call the unsafe lower level functions.
From a quick look, I think there are several other parts of these new APIs that are redundant or overcomplicated.
I will talk with @ConradIrwin about how to proceed here. We have a pair coding call scheduled for Friday.
There was a problem hiding this comment.
I think I did it that way to make it easier to implement remove, but there are probably other approaches we could take.
There was a problem hiding this comment.
Oh, my previous replies were lost.
I think std::vector<std::shared_ptr> sources_ is needed, livekit::AudioMixer AddSouce / RemoveSouce does call into webrtc::AudioMixerImpl, but they just pass the raw pointers there, thus WebRTC lib does not own the object. That is the reason that std::vector<std::shared_ptr> sources_ solve the problem as we need a owner to the AudioMixerSource.
And we need to keep them.
I think Zed solved the racing issue by using Arc.
My suggestion is to make the C++ livekit::AudioMixer thread safe, something like
std::mutex sources_mutex_;
void AudioMixer::add_source(rust::Box<AudioMixerSourceWrapper> source) {
auto native_source = std::make_shared<AudioMixerSource>(std::move(source));
{
std::lock_guard<std::mutex> lock(sources_mutex_);
audio_mixer_->AddSource(native_source.get());
sources_.push_back(native_source);
}
}
void AudioMixer::remove_source(int source_ssrc) {
std::lock_guard<std::mutex> lock(sources_mutex_);
auto it = std::find_if(
sources_.begin(), sources_.end(),
[source_ssrc](const auto& s) { return s->Ssrc() == source_ssrc; });
if (it != sources_.end()) {
audio_mixer_->RemoveSource(it->get());
sources_.erase(it);
}
}
There was a problem hiding this comment.
Good point about the lifetime; AudioMixerImpl in libwebrtc does keep its own vector of sources internally, but those are AudioMixerImpl::SourceStatus structs which have a plain pointer Source* member. So it is helpful to have this vector of std::shared_pointers above it.
We added a mutex guarding add/remove_source to resolve the thread safety issue with that. Unless you see any more thread safety issues, I think it's okay now.
|
Hi @ladvoc , could you please help review the Rust code ? especially on the thread safety. The c++ code is not thread safe but I wonder if that is covered by the Rust somehow |
This allows one to use the apm to cancel echo in multiway calls. Co-Authored-By: Mikayla <mikayla@zed.dev> Co-Authored-By: Zed AI <ai+claude-3.5@zed.dev>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
Co-authored-by: Conrad Irwin <conrad.irwin@gmail.com>
xianshijing-lk
left a comment
There was a problem hiding this comment.
Thanks for addressing the comments, it looks good to me now
|
Ready for merge or are we waiting for another review? |
|
I think you can merge it now |
|
For @ladvoc or @cloudwebrtc , if you have some pending comments, lets make some follow-up PRs to address them |
Well, I can't merge it, that's up to you or someone else at Livekit 😃 |
|
I see. Sorry, I missed that. And just pressed the button here. |
|
Thanks for the great work, and please ping me if you have more PRs to review. |
This allows one to use the apm to cancel echo in multiway calls.
This is a rebase of #613 with merge conflicts fixed.