OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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_audio_capturer.h" | 5 #include "content/renderer/media/webrtc_audio_capturer.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/metrics/histogram.h" | 9 #include "base/metrics/histogram.h" |
10 #include "base/string_util.h" | 10 #include "base/string_util.h" |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
157 // will be overwritten if an external client later calls SetCapturerSource() | 157 // will be overwritten if an external client later calls SetCapturerSource() |
158 // providing an alternative media::AudioCapturerSource. | 158 // providing an alternative media::AudioCapturerSource. |
159 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id), | 159 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id), |
160 channel_layout, | 160 channel_layout, |
161 static_cast<float>(sample_rate)); | 161 static_cast<float>(sample_rate)); |
162 | 162 |
163 return true; | 163 return true; |
164 } | 164 } |
165 | 165 |
166 WebRtcAudioCapturer::WebRtcAudioCapturer() | 166 WebRtcAudioCapturer::WebRtcAudioCapturer() |
167 : source_(NULL), | 167 : default_sink_(NULL), |
| 168 source_(NULL), |
168 running_(false), | 169 running_(false), |
169 agc_is_enabled_(false), | 170 agc_is_enabled_(false), |
170 session_id_(0) { | 171 session_id_(0) { |
171 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; | 172 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; |
172 } | 173 } |
173 | 174 |
174 WebRtcAudioCapturer::~WebRtcAudioCapturer() { | 175 WebRtcAudioCapturer::~WebRtcAudioCapturer() { |
175 DCHECK(thread_checker_.CalledOnValidThread()); | 176 DCHECK(thread_checker_.CalledOnValidThread()); |
176 DCHECK(tracks_.empty()); | 177 DCHECK(tracks_.empty()); |
177 DCHECK(!running_); | 178 DCHECK(!running_); |
| 179 DCHECK(!default_sink_); |
178 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; | 180 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; |
179 } | 181 } |
180 | 182 |
181 void WebRtcAudioCapturer::AddSink( | 183 void WebRtcAudioCapturer::SetDefaultSink(WebRtcAudioCapturerSink* sink) { |
182 WebRtcAudioCapturerSink* track) { | 184 DVLOG(1) << "WebRtcAudioCapturer::SetDefaultSink()"; |
183 DCHECK(thread_checker_.CalledOnValidThread()); | 185 if (sink) { |
| 186 DCHECK(!default_sink_); |
| 187 default_sink_ = sink; |
| 188 AddSink(sink); |
| 189 } else { |
| 190 DCHECK(default_sink_); |
| 191 RemoveSink(default_sink_); |
| 192 default_sink_ = NULL; |
| 193 } |
| 194 } |
| 195 |
| 196 void WebRtcAudioCapturer::AddSink(WebRtcAudioCapturerSink* track) { |
184 DCHECK(track); | 197 DCHECK(track); |
185 DVLOG(1) << "WebRtcAudioCapturer::AddSink()"; | 198 DVLOG(1) << "WebRtcAudioCapturer::AddSink()"; |
| 199 |
| 200 // Start the source if an audio track is connected to the capturer. |
| 201 // |default_sink_| is not an audio track. |
| 202 if (track != default_sink_) |
| 203 Start(); |
| 204 |
186 base::AutoLock auto_lock(lock_); | 205 base::AutoLock auto_lock(lock_); |
187 // Verify that |track| is not already added to the list. | 206 // Verify that |track| is not already added to the list. |
188 DCHECK(std::find_if( | 207 DCHECK(std::find_if( |
189 tracks_.begin(), tracks_.end(), | 208 tracks_.begin(), tracks_.end(), |
190 WebRtcAudioCapturerSinkOwner::WrapsSink(track)) == tracks_.end()); | 209 WebRtcAudioCapturerSinkOwner::WrapsSink(track)) == tracks_.end()); |
191 | 210 |
192 if (buffer_.get()) { | 211 if (buffer_.get()) { |
193 track->SetCaptureFormat(buffer_->params()); | 212 track->SetCaptureFormat(buffer_->params()); |
194 } else { | 213 } else { |
195 DLOG(WARNING) << "The format of the capturer has not been correctly " | 214 DLOG(WARNING) << "The format of the capturer has not been correctly " |
196 << "initialized"; | 215 << "initialized"; |
197 } | 216 } |
198 | 217 |
199 // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns | 218 // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns |
200 // the |track| and delagates all calls to the WebRtcAudioCapturerSink | 219 // the |track| and delagates all calls to the WebRtcAudioCapturerSink |
201 // interface. | 220 // interface. |
202 tracks_.push_back(new WebRtcAudioCapturerSinkOwner(track)); | 221 tracks_.push_back(new WebRtcAudioCapturerSinkOwner(track)); |
203 // TODO(xians): should we call SetCapturerFormat() to each track? | 222 // TODO(xians): should we call SetCapturerFormat() to each track? |
204 } | 223 } |
205 | 224 |
206 void WebRtcAudioCapturer::RemoveSink( | 225 void WebRtcAudioCapturer::RemoveSink( |
207 WebRtcAudioCapturerSink* track) { | 226 WebRtcAudioCapturerSink* track) { |
208 DCHECK(thread_checker_.CalledOnValidThread()); | 227 DCHECK(thread_checker_.CalledOnValidThread()); |
209 DVLOG(1) << "WebRtcAudioCapturer::RemoveSink()"; | 228 DVLOG(1) << "WebRtcAudioCapturer::RemoveSink()"; |
210 | 229 |
211 base::AutoLock auto_lock(lock_); | 230 bool stop_source = false; |
| 231 { |
| 232 base::AutoLock auto_lock(lock_); |
212 | 233 |
213 // Get iterator to the first element for which WrapsSink(track) returns true. | 234 // Get iterator to the first element for which WrapsSink(track) returns |
214 TrackList::iterator it = std::find_if( | 235 // true. |
215 tracks_.begin(), tracks_.end(), | 236 TrackList::iterator it = std::find_if( |
216 WebRtcAudioCapturerSinkOwner::WrapsSink(track)); | 237 tracks_.begin(), tracks_.end(), |
217 if (it != tracks_.end()) { | 238 WebRtcAudioCapturerSinkOwner::WrapsSink(track)); |
218 // Clear the delegate to ensure that no more capture callbacks will | 239 if (it != tracks_.end()) { |
219 // be sent to this sink. Also avoids a possible crash which can happen | 240 // Clear the delegate to ensure that no more capture callbacks will |
220 // if this method is called while capturing is active. | 241 // be sent to this sink. Also avoids a possible crash which can happen |
221 (*it)->Reset(); | 242 // if this method is called while capturing is active. |
222 tracks_.erase(it); | 243 (*it)->Reset(); |
| 244 tracks_.erase(it); |
| 245 } |
| 246 |
| 247 // Stop the source if the last audio track is going away. |
| 248 // The |tracks_| might contain the |default_sink_|, we need to stop the |
| 249 // source if the only remaining element is |default_sink_|. |
| 250 if (tracks_.size() == 1 && default_sink_ && |
| 251 (*tracks_.begin())->IsEqual(default_sink_)) { |
| 252 stop_source = true; |
| 253 } else { |
| 254 // The source might have been stopped, but it is safe to call Stop() |
| 255 // again to make sure the source is stopped correctly. |
| 256 stop_source = tracks_.empty(); |
| 257 } |
223 } | 258 } |
| 259 |
| 260 if (stop_source) |
| 261 Stop(); |
224 } | 262 } |
225 | 263 |
226 void WebRtcAudioCapturer::SetCapturerSource( | 264 void WebRtcAudioCapturer::SetCapturerSource( |
227 const scoped_refptr<media::AudioCapturerSource>& source, | 265 const scoped_refptr<media::AudioCapturerSource>& source, |
228 media::ChannelLayout channel_layout, | 266 media::ChannelLayout channel_layout, |
229 float sample_rate) { | 267 float sample_rate) { |
230 DCHECK(thread_checker_.CalledOnValidThread()); | 268 DCHECK(thread_checker_.CalledOnValidThread()); |
231 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," | 269 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," |
232 << "sample_rate=" << sample_rate << ")"; | 270 << "sample_rate=" << sample_rate << ")"; |
233 scoped_refptr<media::AudioCapturerSource> old_source; | 271 scoped_refptr<media::AudioCapturerSource> old_source; |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
367 } | 405 } |
368 | 406 |
369 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { | 407 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { |
370 base::AutoLock auto_lock(lock_); | 408 base::AutoLock auto_lock(lock_); |
371 // |buffer_| can be NULL when SetCapturerSource() or Initialize() has not | 409 // |buffer_| can be NULL when SetCapturerSource() or Initialize() has not |
372 // been called. | 410 // been called. |
373 return buffer_.get() ? buffer_->params() : media::AudioParameters(); | 411 return buffer_.get() ? buffer_->params() : media::AudioParameters(); |
374 } | 412 } |
375 | 413 |
376 } // namespace content | 414 } // namespace content |
OLD | NEW |