Index: talk/app/webrtc/remoteaudiosource.cc |
diff --git a/talk/app/webrtc/remoteaudiosource.cc b/talk/app/webrtc/remoteaudiosource.cc |
index 41f3d8798a912bb24e897f54c250ab3ed38494c6..a71f26926ee3c57d6950eff3e32710966bb1e25f 100644 |
--- a/talk/app/webrtc/remoteaudiosource.cc |
+++ b/talk/app/webrtc/remoteaudiosource.cc |
@@ -30,43 +30,125 @@ |
#include <algorithm> |
#include <functional> |
+#include "talk/app/webrtc/mediastreamprovider.h" |
+#include "webrtc/base/checks.h" |
#include "webrtc/base/logging.h" |
+#include "webrtc/base/thread.h" |
namespace webrtc { |
-rtc::scoped_refptr<RemoteAudioSource> RemoteAudioSource::Create() { |
- return new rtc::RefCountedObject<RemoteAudioSource>(); |
+class RemoteAudioSource::MessageHandler : public rtc::MessageHandler { |
+ public: |
+ MessageHandler(RemoteAudioSource* source) : source_(source) {} |
+ |
+ private: |
+ ~MessageHandler() override {} |
+ |
+ void OnMessage(rtc::Message* msg) override { |
+ source_->OnMessage(msg); |
+ delete this; |
+ } |
+ |
+ const rtc::scoped_refptr<RemoteAudioSource> source_; |
+ RTC_DISALLOW_COPY_AND_ASSIGN(MessageHandler); |
+}; |
+ |
+rtc::scoped_refptr<RemoteAudioSource> RemoteAudioSource::Create( |
+ uint32_t ssrc, |
+ AudioProviderInterface* provider) { |
+ return new rtc::RefCountedObject<RemoteAudioSource>(ssrc, provider); |
} |
-RemoteAudioSource::RemoteAudioSource() { |
+RemoteAudioSource::RemoteAudioSource(uint32_t ssrc, |
+ AudioProviderInterface* provider) |
+ : ssrc_(ssrc), provider_(provider), main_thread_(rtc::Thread::Current()), |
+ state_(MediaSourceInterface::kLive) { |
+ RTC_DCHECK(provider_); |
+ RTC_DCHECK(main_thread_); |
} |
RemoteAudioSource::~RemoteAudioSource() { |
- ASSERT(audio_observers_.empty()); |
+ RTC_DCHECK(main_thread_->IsCurrent()); |
+ RTC_DCHECK(audio_observers_.empty()); |
+ RTC_DCHECK(sinks_.empty()); |
} |
MediaSourceInterface::SourceState RemoteAudioSource::state() const { |
- return MediaSourceInterface::kLive; |
+ return state_; |
} |
void RemoteAudioSource::SetVolume(double volume) { |
- ASSERT(volume >= 0 && volume <= 10); |
- for (AudioObserverList::iterator it = audio_observers_.begin(); |
- it != audio_observers_.end(); ++it) { |
- (*it)->OnSetVolume(volume); |
+ RTC_DCHECK(volume >= 0 && volume <= 10); |
+ for (auto* observer : audio_observers_) { |
+ observer->OnSetVolume(volume); |
} |
} |
void RemoteAudioSource::RegisterAudioObserver(AudioObserver* observer) { |
- ASSERT(observer != NULL); |
- ASSERT(std::find(audio_observers_.begin(), audio_observers_.end(), |
+ RTC_DCHECK(observer != NULL); |
+ RTC_DCHECK(std::find(audio_observers_.begin(), audio_observers_.end(), |
observer) == audio_observers_.end()); |
audio_observers_.push_back(observer); |
} |
void RemoteAudioSource::UnregisterAudioObserver(AudioObserver* observer) { |
- ASSERT(observer != NULL); |
+ RTC_DCHECK(observer != NULL); |
audio_observers_.remove(observer); |
} |
+void RemoteAudioSource::AddSink(AudioTrackSinkInterface* sink) { |
+ RTC_DCHECK(main_thread_->IsCurrent()); |
+ RTC_DCHECK(sink); |
+ RTC_DCHECK(state_ == MediaSourceInterface::kLive); |
+ |
+ if (!provider_) { |
+ LOG(LS_ERROR) << "No audio provider, so can't set an audio sink."; |
+ return; |
+ } |
+ |
+ if (sinks_.empty()) |
+ provider_->SetRawAudioSink(ssrc_, this); |
+ |
+ rtc::CritScope lock(&sink_lock_); |
+ RTC_DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end()); |
+ sinks_.push_back(sink); |
+} |
+ |
+void RemoteAudioSource::RemoveSink(AudioTrackSinkInterface* sink) { |
+ RTC_DCHECK(main_thread_->IsCurrent()); |
+ RTC_DCHECK(sink); |
+ { |
+ rtc::CritScope lock(&sink_lock_); |
+ sinks_.remove(sink); |
+ } |
+ |
+ if (sinks_.empty() && provider_) |
+ provider_->SetRawAudioSink(ssrc_, nullptr); |
+} |
+ |
+void RemoteAudioSource::OnData(const void* audio_data, |
+ int bits_per_sample, |
+ int sample_rate, |
+ int number_of_channels, |
+ size_t number_of_frames) { |
+ // Called on the externally-owned audio callback thread, via/from webrtc. |
+ rtc::CritScope lock(&sink_lock_); |
+ for (auto* sink : sinks_) { |
+ sink->OnData(audio_data, bits_per_sample, sample_rate, number_of_channels, |
+ number_of_frames); |
+ } |
+} |
+ |
+void RemoteAudioSource::OnClose() { |
perkj_webrtc
2015/12/10 12:24:05
What triggers this?
tommi
2015/12/10 22:37:25
Deletion of the session. It tears down the voice
|
+ main_thread_->Post(new MessageHandler(this)); |
perkj_webrtc
2015/12/10 12:24:05
use async_invoker instead. You don't need the Mess
tommi
2015/12/10 22:37:25
I started doing that but I'm hesitating. Have you
|
+} |
+ |
+void RemoteAudioSource::OnMessage(rtc::Message* msg) { |
+ RTC_DCHECK(main_thread_->IsCurrent()); |
+ provider_ = nullptr; |
+ sinks_.clear(); |
+ state_ = MediaSourceInterface::kEnded; |
+ FireOnChanged(); |
+} |
+ |
} // namespace webrtc |