Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(754)

Side by Side Diff: talk/app/webrtc/remoteaudiosource.cc

Issue 1505253004: Support for remote audio into tracks (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Address comments Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * libjingle 2 * libjingle
3 * Copyright 2014 Google Inc. 3 * Copyright 2014 Google Inc.
4 * 4 *
5 * Redistribution and use in source and binary forms, with or without 5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions are met: 6 * modification, are permitted provided that the following conditions are met:
7 * 7 *
8 * 1. Redistributions of source code must retain the above copyright notice, 8 * 1. Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer. 9 * this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, 10 * 2. Redistributions in binary form must reproduce the above copyright notice,
(...skipping 11 matching lines...) Expand all
22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 22 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */ 26 */
27 27
28 #include "talk/app/webrtc/remoteaudiosource.h" 28 #include "talk/app/webrtc/remoteaudiosource.h"
29 29
30 #include <algorithm> 30 #include <algorithm>
31 #include <functional> 31 #include <functional>
32 #include <utility>
32 33
34 #include "talk/app/webrtc/mediastreamprovider.h"
35 #include "webrtc/base/checks.h"
33 #include "webrtc/base/logging.h" 36 #include "webrtc/base/logging.h"
37 #include "webrtc/base/thread.h"
34 38
35 namespace webrtc { 39 namespace webrtc {
36 40
37 rtc::scoped_refptr<RemoteAudioSource> RemoteAudioSource::Create() { 41 class RemoteAudioSource::MessageHandler : public rtc::MessageHandler {
38 return new rtc::RefCountedObject<RemoteAudioSource>(); 42 public:
43 explicit MessageHandler(RemoteAudioSource* source) : source_(source) {}
44
45 private:
46 ~MessageHandler() override {}
47
48 void OnMessage(rtc::Message* msg) override {
49 source_->OnMessage(msg);
50 delete this;
51 }
52
53 const rtc::scoped_refptr<RemoteAudioSource> source_;
54 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(MessageHandler);
55 };
56
57 class RemoteAudioSource::Sink : public AudioSinkInterface {
58 public:
59 explicit Sink(RemoteAudioSource* source) : source_(source) {}
60 ~Sink() override { source_->OnAudioProviderGone(); }
61
62 private:
63 void OnData(const AudioSinkInterface::Data& audio) override {
64 if (source_)
65 source_->OnData(audio);
66 }
67
68 const rtc::scoped_refptr<RemoteAudioSource> source_;
69 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Sink);
70 };
71
72 rtc::scoped_refptr<RemoteAudioSource> RemoteAudioSource::Create(
73 uint32_t ssrc,
74 AudioProviderInterface* provider) {
75 rtc::scoped_refptr<RemoteAudioSource> ret(
76 new rtc::RefCountedObject<RemoteAudioSource>());
77 ret->Initialize(ssrc, provider);
78 return ret;
39 } 79 }
40 80
41 RemoteAudioSource::RemoteAudioSource() { 81 RemoteAudioSource::RemoteAudioSource()
82 : main_thread_(rtc::Thread::Current()),
83 state_(MediaSourceInterface::kLive) {
84 RTC_DCHECK(main_thread_);
42 } 85 }
43 86
44 RemoteAudioSource::~RemoteAudioSource() { 87 RemoteAudioSource::~RemoteAudioSource() {
45 ASSERT(audio_observers_.empty()); 88 RTC_DCHECK(main_thread_->IsCurrent());
89 RTC_DCHECK(audio_observers_.empty());
90 RTC_DCHECK(sinks_.empty());
91 }
92
93 void RemoteAudioSource::Initialize(uint32_t ssrc,
94 AudioProviderInterface* provider) {
95 RTC_DCHECK(main_thread_->IsCurrent());
96 // To make sure we always get notified when the provider goes out of scope,
97 // we register for callbacks here and not on demand in AddSink.
98 if (provider) { // May be null in tests.
99 provider->SetRawAudioSink(
100 ssrc, std::move(rtc::scoped_ptr<AudioSinkInterface>(new Sink(this))));
101 }
46 } 102 }
47 103
48 MediaSourceInterface::SourceState RemoteAudioSource::state() const { 104 MediaSourceInterface::SourceState RemoteAudioSource::state() const {
49 return MediaSourceInterface::kLive; 105 RTC_DCHECK(main_thread_->IsCurrent());
106 return state_;
50 } 107 }
51 108
52 void RemoteAudioSource::SetVolume(double volume) { 109 void RemoteAudioSource::SetVolume(double volume) {
53 ASSERT(volume >= 0 && volume <= 10); 110 RTC_DCHECK(volume >= 0 && volume <= 10);
54 for (AudioObserverList::iterator it = audio_observers_.begin(); 111 for (auto* observer : audio_observers_)
55 it != audio_observers_.end(); ++it) { 112 observer->OnSetVolume(volume);
56 (*it)->OnSetVolume(volume);
57 }
58 } 113 }
59 114
60 void RemoteAudioSource::RegisterAudioObserver(AudioObserver* observer) { 115 void RemoteAudioSource::RegisterAudioObserver(AudioObserver* observer) {
61 ASSERT(observer != NULL); 116 RTC_DCHECK(observer != NULL);
62 ASSERT(std::find(audio_observers_.begin(), audio_observers_.end(), 117 RTC_DCHECK(std::find(audio_observers_.begin(), audio_observers_.end(),
63 observer) == audio_observers_.end()); 118 observer) == audio_observers_.end());
64 audio_observers_.push_back(observer); 119 audio_observers_.push_back(observer);
65 } 120 }
66 121
67 void RemoteAudioSource::UnregisterAudioObserver(AudioObserver* observer) { 122 void RemoteAudioSource::UnregisterAudioObserver(AudioObserver* observer) {
68 ASSERT(observer != NULL); 123 RTC_DCHECK(observer != NULL);
69 audio_observers_.remove(observer); 124 audio_observers_.remove(observer);
70 } 125 }
71 126
127 void RemoteAudioSource::AddSink(AudioTrackSinkInterface* sink) {
128 RTC_DCHECK(main_thread_->IsCurrent());
129 RTC_DCHECK(sink);
130
131 if (state_ != MediaSourceInterface::kLive) {
132 LOG(LS_ERROR) << "Can't register sink as the source isn't live.";
133 return;
134 }
135
136 rtc::CritScope lock(&sink_lock_);
137 RTC_DCHECK(std::find(sinks_.begin(), sinks_.end(), sink) == sinks_.end());
138 sinks_.push_back(sink);
139 }
140
141 void RemoteAudioSource::RemoveSink(AudioTrackSinkInterface* sink) {
142 RTC_DCHECK(main_thread_->IsCurrent());
143 RTC_DCHECK(sink);
144
145 rtc::CritScope lock(&sink_lock_);
146 sinks_.remove(sink);
147 }
148
149 void RemoteAudioSource::OnData(const AudioSinkInterface::Data& audio) {
150 // Called on the externally-owned audio callback thread, via/from webrtc.
151 rtc::CritScope lock(&sink_lock_);
152 for (auto* sink : sinks_) {
153 sink->OnData(audio.data, 16, audio.sample_rate, audio.channels,
154 audio.samples_per_channel);
155 }
156 }
157
158 void RemoteAudioSource::OnAudioProviderGone() {
159 // Called when the data provider is deleted. It may be the worker thread
160 // in libjingle or may be a different worker thread.
161 main_thread_->Post(new MessageHandler(this));
162 }
163
164 void RemoteAudioSource::OnMessage(rtc::Message* msg) {
165 RTC_DCHECK(main_thread_->IsCurrent());
166 sinks_.clear();
167 state_ = MediaSourceInterface::kEnded;
168 FireOnChanged();
169 }
170
72 } // namespace webrtc 171 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698