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

Side by Side Diff: content/renderer/media/webrtc_audio_capturer.cc

Issue 15979027: start/stop the source of the capturer when 1st audiotrack/last audiotrack is added/removed (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: addressed Henrik's comments. Created 7 years, 6 months 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 | Annotate | Revision Log
OLDNEW
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
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
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
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_capturer.h ('k') | content/renderer/media/webrtc_audio_device_impl.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698