Index: content/renderer/media/webrtc_audio_capturer.cc |
diff --git a/content/renderer/media/webrtc_audio_capturer.cc b/content/renderer/media/webrtc_audio_capturer.cc |
index 0f35b4f59f1118bd3fafdafbb9975b4c3160ca6b..a279163ac45649c939637e166c556b633d6bc793 100644 |
--- a/content/renderer/media/webrtc_audio_capturer.cc |
+++ b/content/renderer/media/webrtc_audio_capturer.cc |
@@ -164,7 +164,8 @@ bool WebRtcAudioCapturer::Initialize(int render_view_id, |
} |
WebRtcAudioCapturer::WebRtcAudioCapturer() |
- : source_(NULL), |
+ : default_sink_(NULL), |
+ source_(NULL), |
running_(false), |
agc_is_enabled_(false), |
session_id_(0) { |
@@ -175,14 +176,32 @@ WebRtcAudioCapturer::~WebRtcAudioCapturer() { |
DCHECK(thread_checker_.CalledOnValidThread()); |
DCHECK(tracks_.empty()); |
DCHECK(!running_); |
+ DCHECK(!default_sink_); |
DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; |
} |
-void WebRtcAudioCapturer::AddSink( |
- WebRtcAudioCapturerSink* track) { |
- DCHECK(thread_checker_.CalledOnValidThread()); |
+void WebRtcAudioCapturer::SetDefaultSink(WebRtcAudioCapturerSink* sink) { |
+ DVLOG(1) << "WebRtcAudioCapturer::SetDefaultSink()"; |
+ if (sink) { |
+ DCHECK(!default_sink_); |
+ default_sink_ = sink; |
+ AddSink(sink); |
+ } else { |
+ DCHECK(default_sink_); |
+ RemoveSink(default_sink_); |
+ default_sink_ = NULL; |
+ } |
+} |
+ |
+void WebRtcAudioCapturer::AddSink(WebRtcAudioCapturerSink* track) { |
DCHECK(track); |
DVLOG(1) << "WebRtcAudioCapturer::AddSink()"; |
+ |
+ // Start the source if an audio track is connected to the capturer. |
+ // |default_sink_| is not an audio track. |
+ if (track != default_sink_) |
+ Start(); |
+ |
base::AutoLock auto_lock(lock_); |
// Verify that |track| is not already added to the list. |
DCHECK(std::find_if( |
@@ -208,19 +227,38 @@ void WebRtcAudioCapturer::RemoveSink( |
DCHECK(thread_checker_.CalledOnValidThread()); |
DVLOG(1) << "WebRtcAudioCapturer::RemoveSink()"; |
- base::AutoLock auto_lock(lock_); |
+ bool stop_source = false; |
+ { |
+ base::AutoLock auto_lock(lock_); |
- // Get iterator to the first element for which WrapsSink(track) returns true. |
- TrackList::iterator it = std::find_if( |
- tracks_.begin(), tracks_.end(), |
- WebRtcAudioCapturerSinkOwner::WrapsSink(track)); |
- if (it != tracks_.end()) { |
- // Clear the delegate to ensure that no more capture callbacks will |
- // be sent to this sink. Also avoids a possible crash which can happen |
- // if this method is called while capturing is active. |
- (*it)->Reset(); |
- tracks_.erase(it); |
+ // Get iterator to the first element for which WrapsSink(track) returns |
+ // true. |
+ TrackList::iterator it = std::find_if( |
+ tracks_.begin(), tracks_.end(), |
+ WebRtcAudioCapturerSinkOwner::WrapsSink(track)); |
+ if (it != tracks_.end()) { |
+ // Clear the delegate to ensure that no more capture callbacks will |
+ // be sent to this sink. Also avoids a possible crash which can happen |
+ // if this method is called while capturing is active. |
+ (*it)->Reset(); |
+ tracks_.erase(it); |
+ } |
+ |
+ // Stop the source if the last audio track is going away. |
+ // The |tracks_| might contain the |default_sink_|, we need to stop the |
+ // source if the only remaining element is |default_sink_|. |
+ if (tracks_.size() == 1 && default_sink_ && |
+ (*tracks_.begin())->IsEqual(default_sink_)) { |
+ stop_source = true; |
+ } else { |
+ // The source might have been stopped, but it is safe to call Stop() |
+ // again to make sure the source is stopped correctly. |
+ stop_source = tracks_.empty(); |
+ } |
} |
+ |
+ if (stop_source) |
+ Stop(); |
} |
void WebRtcAudioCapturer::SetCapturerSource( |