| 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 |