OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" | 5 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "content/renderer/media/media_stream_audio_processor.h" | 8 #include "content/renderer/media/media_stream_audio_processor.h" |
| 9 #include "content/renderer/media/webrtc/peer_connection_dependency_factory.h" |
9 #include "content/renderer/media/webrtc/webrtc_audio_sink_adapter.h" | 10 #include "content/renderer/media/webrtc/webrtc_audio_sink_adapter.h" |
10 #include "content/renderer/media/webrtc_local_audio_track.h" | 11 #include "content/renderer/media/webrtc_local_audio_track.h" |
| 12 #include "content/renderer/render_thread_impl.h" |
11 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" | 13 #include "third_party/libjingle/source/talk/app/webrtc/mediastreaminterface.h" |
12 | 14 |
13 namespace content { | 15 namespace content { |
14 | 16 |
15 static const char kAudioTrackKind[] = "audio"; | 17 static const char kAudioTrackKind[] = "audio"; |
16 | 18 |
17 scoped_refptr<WebRtcLocalAudioTrackAdapter> | 19 scoped_refptr<WebRtcLocalAudioTrackAdapter> |
18 WebRtcLocalAudioTrackAdapter::Create( | 20 WebRtcLocalAudioTrackAdapter::Create( |
19 const std::string& label, | 21 const std::string& label, |
20 webrtc::AudioSourceInterface* track_source) { | 22 webrtc::AudioSourceInterface* track_source) { |
| 23 // TODO(tommi): Change this so that the signaling thread is one of the |
| 24 // parameters to this method. |
| 25 scoped_refptr<base::MessageLoopProxy> signaling_thread; |
| 26 RenderThreadImpl* current = RenderThreadImpl::current(); |
| 27 if (current) { |
| 28 PeerConnectionDependencyFactory* pc_factory = |
| 29 current->GetPeerConnectionDependencyFactory(); |
| 30 signaling_thread = pc_factory->GetWebRtcSignalingThread(); |
| 31 } |
| 32 |
| 33 LOG_IF(ERROR, !signaling_thread.get()) << "No signaling thread!"; |
| 34 |
21 rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>* adapter = | 35 rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>* adapter = |
22 new rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>( | 36 new rtc::RefCountedObject<WebRtcLocalAudioTrackAdapter>( |
23 label, track_source); | 37 label, track_source, signaling_thread); |
24 return adapter; | 38 return adapter; |
25 } | 39 } |
26 | 40 |
27 WebRtcLocalAudioTrackAdapter::WebRtcLocalAudioTrackAdapter( | 41 WebRtcLocalAudioTrackAdapter::WebRtcLocalAudioTrackAdapter( |
28 const std::string& label, | 42 const std::string& label, |
29 webrtc::AudioSourceInterface* track_source) | 43 webrtc::AudioSourceInterface* track_source, |
| 44 const scoped_refptr<base::SingleThreadTaskRunner>& signaling_thread) |
30 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label), | 45 : webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>(label), |
31 owner_(NULL), | 46 owner_(NULL), |
32 track_source_(track_source), | 47 track_source_(track_source), |
| 48 signaling_thread_(signaling_thread), |
33 signal_level_(0) { | 49 signal_level_(0) { |
34 signaling_thread_.DetachFromThread(); | 50 signaling_thread_checker_.DetachFromThread(); |
35 capture_thread_.DetachFromThread(); | 51 capture_thread_.DetachFromThread(); |
36 } | 52 } |
37 | 53 |
38 WebRtcLocalAudioTrackAdapter::~WebRtcLocalAudioTrackAdapter() { | 54 WebRtcLocalAudioTrackAdapter::~WebRtcLocalAudioTrackAdapter() { |
39 } | 55 } |
40 | 56 |
41 void WebRtcLocalAudioTrackAdapter::Initialize(WebRtcLocalAudioTrack* owner) { | 57 void WebRtcLocalAudioTrackAdapter::Initialize(WebRtcLocalAudioTrack* owner) { |
42 DCHECK(!owner_); | 58 DCHECK(!owner_); |
43 DCHECK(owner); | 59 DCHECK(owner); |
44 owner_ = owner; | 60 owner_ = owner; |
45 } | 61 } |
46 | 62 |
47 void WebRtcLocalAudioTrackAdapter::SetAudioProcessor( | 63 void WebRtcLocalAudioTrackAdapter::SetAudioProcessor( |
48 const scoped_refptr<MediaStreamAudioProcessor>& processor) { | 64 const scoped_refptr<MediaStreamAudioProcessor>& processor) { |
49 // SetAudioProcessor will be called when a new capture thread has been | 65 // SetAudioProcessor will be called when a new capture thread has been |
50 // initialized, so we need to detach from any current capture thread we're | 66 // initialized, so we need to detach from any current capture thread we're |
51 // checking and attach to the current one. | 67 // checking and attach to the current one. |
52 capture_thread_.DetachFromThread(); | 68 capture_thread_.DetachFromThread(); |
53 DCHECK(capture_thread_.CalledOnValidThread()); | 69 DCHECK(capture_thread_.CalledOnValidThread()); |
54 base::AutoLock auto_lock(lock_); | 70 base::AutoLock auto_lock(lock_); |
55 audio_processor_ = processor; | 71 audio_processor_ = processor; |
56 } | 72 } |
57 | 73 |
58 std::string WebRtcLocalAudioTrackAdapter::kind() const { | 74 std::string WebRtcLocalAudioTrackAdapter::kind() const { |
59 return kAudioTrackKind; | 75 return kAudioTrackKind; |
60 } | 76 } |
61 | 77 |
| 78 bool WebRtcLocalAudioTrackAdapter::set_enabled(bool enable) { |
| 79 // If we're not called on the signaling thread, we need to post a task to |
| 80 // change the state on the correct thread. |
| 81 if (signaling_thread_.get() && !signaling_thread_->BelongsToCurrentThread()) { |
| 82 signaling_thread_->PostTask(FROM_HERE, |
| 83 base::Bind( |
| 84 base::IgnoreResult(&WebRtcLocalAudioTrackAdapter::set_enabled), |
| 85 this, enable)); |
| 86 return true; |
| 87 } |
| 88 |
| 89 return webrtc::MediaStreamTrack<webrtc::AudioTrackInterface>:: |
| 90 set_enabled(enable); |
| 91 } |
| 92 |
62 void WebRtcLocalAudioTrackAdapter::AddSink( | 93 void WebRtcLocalAudioTrackAdapter::AddSink( |
63 webrtc::AudioTrackSinkInterface* sink) { | 94 webrtc::AudioTrackSinkInterface* sink) { |
64 DCHECK(signaling_thread_.CalledOnValidThread()); | 95 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
65 DCHECK(sink); | 96 DCHECK(sink); |
66 #ifndef NDEBUG | 97 #ifndef NDEBUG |
67 // Verify that |sink| has not been added. | 98 // Verify that |sink| has not been added. |
68 for (ScopedVector<WebRtcAudioSinkAdapter>::const_iterator it = | 99 for (ScopedVector<WebRtcAudioSinkAdapter>::const_iterator it = |
69 sink_adapters_.begin(); | 100 sink_adapters_.begin(); |
70 it != sink_adapters_.end(); ++it) { | 101 it != sink_adapters_.end(); ++it) { |
71 DCHECK(!(*it)->IsEqual(sink)); | 102 DCHECK(!(*it)->IsEqual(sink)); |
72 } | 103 } |
73 #endif | 104 #endif |
74 | 105 |
75 scoped_ptr<WebRtcAudioSinkAdapter> adapter( | 106 scoped_ptr<WebRtcAudioSinkAdapter> adapter( |
76 new WebRtcAudioSinkAdapter(sink)); | 107 new WebRtcAudioSinkAdapter(sink)); |
77 owner_->AddSink(adapter.get()); | 108 owner_->AddSink(adapter.get()); |
78 sink_adapters_.push_back(adapter.release()); | 109 sink_adapters_.push_back(adapter.release()); |
79 } | 110 } |
80 | 111 |
81 void WebRtcLocalAudioTrackAdapter::RemoveSink( | 112 void WebRtcLocalAudioTrackAdapter::RemoveSink( |
82 webrtc::AudioTrackSinkInterface* sink) { | 113 webrtc::AudioTrackSinkInterface* sink) { |
83 DCHECK(signaling_thread_.CalledOnValidThread()); | 114 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
84 DCHECK(sink); | 115 DCHECK(sink); |
85 for (ScopedVector<WebRtcAudioSinkAdapter>::iterator it = | 116 for (ScopedVector<WebRtcAudioSinkAdapter>::iterator it = |
86 sink_adapters_.begin(); | 117 sink_adapters_.begin(); |
87 it != sink_adapters_.end(); ++it) { | 118 it != sink_adapters_.end(); ++it) { |
88 if ((*it)->IsEqual(sink)) { | 119 if ((*it)->IsEqual(sink)) { |
89 owner_->RemoveSink(*it); | 120 owner_->RemoveSink(*it); |
90 sink_adapters_.erase(it); | 121 sink_adapters_.erase(it); |
91 return; | 122 return; |
92 } | 123 } |
93 } | 124 } |
94 } | 125 } |
95 | 126 |
96 bool WebRtcLocalAudioTrackAdapter::GetSignalLevel(int* level) { | 127 bool WebRtcLocalAudioTrackAdapter::GetSignalLevel(int* level) { |
97 DCHECK(signaling_thread_.CalledOnValidThread()); | 128 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
98 | 129 |
99 // It is required to provide the signal level after audio processing. In | 130 // It is required to provide the signal level after audio processing. In |
100 // case the audio processing is not enabled for the track, we return | 131 // case the audio processing is not enabled for the track, we return |
101 // false here in order not to overwrite the value from WebRTC. | 132 // false here in order not to overwrite the value from WebRTC. |
102 // TODO(xians): Remove this after we turn on the APM in Chrome by default. | 133 // TODO(xians): Remove this after we turn on the APM in Chrome by default. |
103 // http://crbug/365672 . | 134 // http://crbug/365672 . |
104 if (!MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()) | 135 if (!MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()) |
105 return false; | 136 return false; |
106 | 137 |
107 base::AutoLock auto_lock(lock_); | 138 base::AutoLock auto_lock(lock_); |
108 *level = signal_level_; | 139 *level = signal_level_; |
109 return true; | 140 return true; |
110 } | 141 } |
111 | 142 |
112 rtc::scoped_refptr<webrtc::AudioProcessorInterface> | 143 rtc::scoped_refptr<webrtc::AudioProcessorInterface> |
113 WebRtcLocalAudioTrackAdapter::GetAudioProcessor() { | 144 WebRtcLocalAudioTrackAdapter::GetAudioProcessor() { |
114 DCHECK(signaling_thread_.CalledOnValidThread()); | 145 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
115 base::AutoLock auto_lock(lock_); | 146 base::AutoLock auto_lock(lock_); |
116 return audio_processor_.get(); | 147 return audio_processor_.get(); |
117 } | 148 } |
118 | 149 |
119 std::vector<int> WebRtcLocalAudioTrackAdapter::VoeChannels() const { | 150 std::vector<int> WebRtcLocalAudioTrackAdapter::VoeChannels() const { |
120 DCHECK(capture_thread_.CalledOnValidThread()); | 151 DCHECK(capture_thread_.CalledOnValidThread()); |
121 base::AutoLock auto_lock(lock_); | 152 base::AutoLock auto_lock(lock_); |
122 return voe_channels_; | 153 return voe_channels_; |
123 } | 154 } |
124 | 155 |
125 void WebRtcLocalAudioTrackAdapter::SetSignalLevel(int signal_level) { | 156 void WebRtcLocalAudioTrackAdapter::SetSignalLevel(int signal_level) { |
126 DCHECK(capture_thread_.CalledOnValidThread()); | 157 DCHECK(capture_thread_.CalledOnValidThread()); |
127 base::AutoLock auto_lock(lock_); | 158 base::AutoLock auto_lock(lock_); |
128 signal_level_ = signal_level; | 159 signal_level_ = signal_level; |
129 } | 160 } |
130 | 161 |
131 void WebRtcLocalAudioTrackAdapter::AddChannel(int channel_id) { | 162 void WebRtcLocalAudioTrackAdapter::AddChannel(int channel_id) { |
132 DCHECK(signaling_thread_.CalledOnValidThread()); | 163 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
133 DVLOG(1) << "WebRtcLocalAudioTrack::AddChannel(channel_id=" | 164 DVLOG(1) << "WebRtcLocalAudioTrack::AddChannel(channel_id=" |
134 << channel_id << ")"; | 165 << channel_id << ")"; |
135 base::AutoLock auto_lock(lock_); | 166 base::AutoLock auto_lock(lock_); |
136 if (std::find(voe_channels_.begin(), voe_channels_.end(), channel_id) != | 167 if (std::find(voe_channels_.begin(), voe_channels_.end(), channel_id) != |
137 voe_channels_.end()) { | 168 voe_channels_.end()) { |
138 // We need to handle the case when the same channel is connected to the | 169 // We need to handle the case when the same channel is connected to the |
139 // track more than once. | 170 // track more than once. |
140 return; | 171 return; |
141 } | 172 } |
142 | 173 |
143 voe_channels_.push_back(channel_id); | 174 voe_channels_.push_back(channel_id); |
144 } | 175 } |
145 | 176 |
146 void WebRtcLocalAudioTrackAdapter::RemoveChannel(int channel_id) { | 177 void WebRtcLocalAudioTrackAdapter::RemoveChannel(int channel_id) { |
147 DCHECK(signaling_thread_.CalledOnValidThread()); | 178 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
148 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveChannel(channel_id=" | 179 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveChannel(channel_id=" |
149 << channel_id << ")"; | 180 << channel_id << ")"; |
150 base::AutoLock auto_lock(lock_); | 181 base::AutoLock auto_lock(lock_); |
151 std::vector<int>::iterator iter = | 182 std::vector<int>::iterator iter = |
152 std::find(voe_channels_.begin(), voe_channels_.end(), channel_id); | 183 std::find(voe_channels_.begin(), voe_channels_.end(), channel_id); |
153 DCHECK(iter != voe_channels_.end()); | 184 DCHECK(iter != voe_channels_.end()); |
154 voe_channels_.erase(iter); | 185 voe_channels_.erase(iter); |
155 } | 186 } |
156 | 187 |
157 webrtc::AudioSourceInterface* WebRtcLocalAudioTrackAdapter::GetSource() const { | 188 webrtc::AudioSourceInterface* WebRtcLocalAudioTrackAdapter::GetSource() const { |
158 DCHECK(signaling_thread_.CalledOnValidThread()); | 189 DCHECK(signaling_thread_checker_.CalledOnValidThread()); |
159 return track_source_; | 190 return track_source_; |
160 } | 191 } |
161 | 192 |
162 cricket::AudioRenderer* WebRtcLocalAudioTrackAdapter::GetRenderer() { | 193 cricket::AudioRenderer* WebRtcLocalAudioTrackAdapter::GetRenderer() { |
163 // When the audio track processing is enabled, return a NULL so that capture | 194 // When the audio track processing is enabled, return a NULL so that capture |
164 // data goes through Libjingle LocalAudioTrackHandler::LocalAudioSinkAdapter | 195 // data goes through Libjingle LocalAudioTrackHandler::LocalAudioSinkAdapter |
165 // ==> WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer ==> WebRTC. | 196 // ==> WebRtcVoiceMediaChannel::WebRtcVoiceChannelRenderer ==> WebRTC. |
166 // When the audio track processing is disabled, WebRtcLocalAudioTrackAdapter | 197 // When the audio track processing is disabled, WebRtcLocalAudioTrackAdapter |
167 // is used to pass the channel ids to WebRtcAudioDeviceImpl, the data flow | 198 // is used to pass the channel ids to WebRtcAudioDeviceImpl, the data flow |
168 // becomes WebRtcAudioDeviceImpl ==> WebRTC. | 199 // becomes WebRtcAudioDeviceImpl ==> WebRTC. |
169 // TODO(xians): Only return NULL after the APM in WebRTC is deprecated. | 200 // TODO(xians): Only return NULL after the APM in WebRTC is deprecated. |
170 // See See http://crbug/365672 for details. | 201 // See See http://crbug/365672 for details. |
171 return MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()? | 202 return MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled()? |
172 NULL : this; | 203 NULL : this; |
173 } | 204 } |
174 | 205 |
175 } // namespace content | 206 } // namespace content |
OLD | NEW |