Configure media flow correctly with Unified Plan
This also changes RtpReceiver and RemoteAudioSource to have two-step
initialization, since in Unified Plan RtpReceivers are created much
earlier than in Plan B.
Bug: webrtc:7600
Change-Id: Ia135d25eb8bcab22969007b3a825a5a43ce62bf4
Reviewed-on: https://webrtc-review.googlesource.com/39382
Reviewed-by: Peter Thatcher <pthatcher@webrtc.org>
Commit-Queue: Steve Anton <steveanton@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#21681}diff --git a/pc/remoteaudiosource.cc b/pc/remoteaudiosource.cc
index a260be8..f58e23d 100644
--- a/pc/remoteaudiosource.cc
+++ b/pc/remoteaudiosource.cc
@@ -23,35 +23,33 @@
namespace webrtc {
-class RemoteAudioSource::Sink : public AudioSinkInterface {
+// This proxy is passed to the underlying media engine to receive audio data as
+// they come in. The data will then be passed back up to the RemoteAudioSource
+// which will fan it out to all the sinks that have been added to it.
+class RemoteAudioSource::AudioDataProxy : public AudioSinkInterface {
public:
- explicit Sink(RemoteAudioSource* source) : source_(source) {}
- ~Sink() override { source_->OnAudioChannelGone(); }
+ explicit AudioDataProxy(RemoteAudioSource* source) : source_(source) {
+ RTC_DCHECK(source);
+ }
+ ~AudioDataProxy() override { source_->OnAudioChannelGone(); }
- private:
+ // AudioSinkInterface implementation.
void OnData(const AudioSinkInterface::Data& audio) override {
- if (source_)
- source_->OnData(audio);
+ source_->OnData(audio);
}
+ private:
const rtc::scoped_refptr<RemoteAudioSource> source_;
- RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Sink);
+
+ RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(AudioDataProxy);
};
-rtc::scoped_refptr<RemoteAudioSource> RemoteAudioSource::Create(
- rtc::Thread* worker_thread,
- cricket::VoiceMediaChannel* media_channel,
- uint32_t ssrc) {
- rtc::scoped_refptr<RemoteAudioSource> ret(
- new rtc::RefCountedObject<RemoteAudioSource>());
- ret->Initialize(worker_thread, media_channel, ssrc);
- return ret;
-}
-
-RemoteAudioSource::RemoteAudioSource()
+RemoteAudioSource::RemoteAudioSource(rtc::Thread* worker_thread)
: main_thread_(rtc::Thread::Current()),
+ worker_thread_(worker_thread),
state_(MediaSourceInterface::kLive) {
RTC_DCHECK(main_thread_);
+ RTC_DCHECK(worker_thread_);
}
RemoteAudioSource::~RemoteAudioSource() {
@@ -60,17 +58,24 @@
RTC_DCHECK(sinks_.empty());
}
-void RemoteAudioSource::Initialize(rtc::Thread* worker_thread,
- cricket::VoiceMediaChannel* media_channel,
- uint32_t ssrc) {
- RTC_DCHECK(main_thread_->IsCurrent());
- // To make sure we always get notified when the channel goes out of scope,
- // we register for callbacks here and not on demand in AddSink.
- if (media_channel) { // May be null in tests.
- worker_thread->Invoke<void>(RTC_FROM_HERE, [&] {
- media_channel->SetRawAudioSink(ssrc, rtc::MakeUnique<Sink>(this));
- });
- }
+void RemoteAudioSource::Start(cricket::VoiceMediaChannel* media_channel,
+ uint32_t ssrc) {
+ RTC_DCHECK_RUN_ON(main_thread_);
+ RTC_DCHECK(media_channel);
+ // Register for callbacks immediately before AddSink so that we always get
+ // notified when a channel goes out of scope (signaled when "AudioDataProxy"
+ // is destroyed).
+ worker_thread_->Invoke<void>(RTC_FROM_HERE, [&] {
+ media_channel->SetRawAudioSink(ssrc, rtc::MakeUnique<AudioDataProxy>(this));
+ });
+}
+
+void RemoteAudioSource::Stop(cricket::VoiceMediaChannel* media_channel,
+ uint32_t ssrc) {
+ RTC_DCHECK_RUN_ON(main_thread_);
+ RTC_DCHECK(media_channel);
+ worker_thread_->Invoke<void>(
+ RTC_FROM_HERE, [&] { media_channel->SetRawAudioSink(ssrc, nullptr); });
}
MediaSourceInterface::SourceState RemoteAudioSource::state() const {
@@ -86,8 +91,9 @@
void RemoteAudioSource::SetVolume(double volume) {
RTC_DCHECK_GE(volume, 0);
RTC_DCHECK_LE(volume, 10);
- for (auto* observer : audio_observers_)
+ for (auto* observer : audio_observers_) {
observer->OnSetVolume(volume);
+ }
}
void RemoteAudioSource::RegisterAudioObserver(AudioObserver* observer) {