Chromium Code Reviews| 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 |