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

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

Issue 90743004: Add generic interfaces for the sinks of the media stream audio track (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed the nits. Created 7 years 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_local_audio_track.h" 5 #include "content/renderer/media/webrtc_local_audio_track.h"
6 6
7 #include "content/public/renderer/media_stream_audio_sink.h"
8 #include "content/renderer/media/media_stream_audio_sink_owner.h"
9 #include "content/renderer/media/media_stream_audio_track_sink.h"
10 #include "content/renderer/media/peer_connection_audio_sink_owner.h"
7 #include "content/renderer/media/webaudio_capturer_source.h" 11 #include "content/renderer/media/webaudio_capturer_source.h"
8 #include "content/renderer/media/webrtc_audio_capturer.h" 12 #include "content/renderer/media/webrtc_audio_capturer.h"
9 #include "content/renderer/media/webrtc_audio_capturer_sink_owner.h"
10 #include "content/renderer/media/webrtc_local_audio_source_provider.h" 13 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
11 #include "media/base/audio_fifo.h" 14 #include "media/base/audio_fifo.h"
12 #include "third_party/libjingle/source/talk/media/base/audiorenderer.h" 15 #include "third_party/libjingle/source/talk/media/base/audiorenderer.h"
13 16
14 namespace content { 17 namespace content {
15 18
16 static const size_t kMaxNumberOfBuffersInFifo = 2; 19 static const size_t kMaxNumberOfBuffersInFifo = 2;
17 static const char kAudioTrackKind[] = "audio"; 20 static const char kAudioTrackKind[] = "audio";
18 21
19 namespace { 22 namespace {
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after
172 voe_channels = voe_channels_; 175 voe_channels = voe_channels_;
173 sinks = sinks_; 176 sinks = sinks_;
174 std::swap(sinks_to_notify_format_, sinks_to_notify_format); 177 std::swap(sinks_to_notify_format_, sinks_to_notify_format);
175 is_webaudio_source = (webaudio_source_.get() != NULL); 178 is_webaudio_source = (webaudio_source_.get() != NULL);
176 } 179 }
177 180
178 // Notify the tracks on when the format changes. This will do nothing if 181 // Notify the tracks on when the format changes. This will do nothing if
179 // |sinks_to_notify_format| is empty. 182 // |sinks_to_notify_format| is empty.
180 for (SinkList::const_iterator it = sinks_to_notify_format.begin(); 183 for (SinkList::const_iterator it = sinks_to_notify_format.begin();
181 it != sinks_to_notify_format.end(); ++it) { 184 it != sinks_to_notify_format.end(); ++it) {
182 (*it)->SetCaptureFormat(buffer_->params()); 185 (*it)->OnSetFormat(buffer_->params());
183 } 186 }
184 187
185 // Push the data to the fifo. 188 // Push the data to the fifo.
186 buffer_->Push(audio_source); 189 buffer_->Push(audio_source);
187 190
188 // When the source is WebAudio, turn off the audio processing if the delay 191 // When the source is WebAudio, turn off the audio processing if the delay
189 // value is 0 even though the constraint is set to true. In such case, it 192 // value is 0 even though the constraint is set to true. In such case, it
190 // indicates the data is not from microphone. 193 // indicates the data is not from microphone.
191 // TODO(xians): remove the flag when supporting one APM per audio track. 194 // TODO(xians): remove the flag when supporting one APM per audio track.
192 // See crbug/264611 for details. 195 // See crbug/264611 for details.
193 bool need_audio_processing = need_audio_processing_; 196 bool need_audio_processing = need_audio_processing_;
194 if (is_webaudio_source && need_audio_processing) 197 if (is_webaudio_source && need_audio_processing)
195 need_audio_processing = (audio_delay_milliseconds != 0); 198 need_audio_processing = (audio_delay_milliseconds != 0);
196 199
197 int current_volume = volume; 200 int current_volume = volume;
198 while (buffer_->Consume()) { 201 while (buffer_->Consume()) {
199 // Feed the data to the sinks. 202 // Feed the data to the sinks.
200 // TODO (jiayl): we should not pass the real audio data down if the track is 203 // TODO (jiayl): we should not pass the real audio data down if the track is
201 // disabled. This is currently done so to feed input to WebRTC typing 204 // disabled. This is currently done so to feed input to WebRTC typing
202 // detection and should be changed when audio processing is moved from 205 // detection and should be changed when audio processing is moved from
203 // WebRTC to the track. 206 // WebRTC to the track.
204 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) { 207 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) {
205 int new_volume = (*it)->CaptureData(voe_channels, 208 int new_volume = (*it)->OnData(buffer_->buffer(),
206 buffer_->buffer(), 209 buffer_->params().sample_rate(),
207 buffer_->params().sample_rate(), 210 buffer_->params().channels(),
208 buffer_->params().channels(), 211 buffer_->params().frames_per_buffer(),
209 buffer_->params().frames_per_buffer(), 212 voe_channels,
210 audio_delay_milliseconds, 213 audio_delay_milliseconds,
211 current_volume, 214 current_volume,
212 need_audio_processing, 215 need_audio_processing,
213 key_pressed); 216 key_pressed);
214 if (new_volume != 0 && capturer.get()) { 217 if (new_volume != 0 && capturer.get()) {
215 // Feed the new volume to WebRtc while changing the volume on the 218 // Feed the new volume to WebRtc while changing the volume on the
216 // browser. 219 // browser.
217 capturer->SetVolume(new_volume); 220 capturer->SetVolume(new_volume);
218 current_volume = new_volume; 221 current_volume = new_volume;
219 } 222 }
220 } 223 }
221 } 224 }
222 } 225 }
223 226
224 void WebRtcLocalAudioTrack::SetCaptureFormat( 227 void WebRtcLocalAudioTrack::OnSetFormat(
225 const media::AudioParameters& params) { 228 const media::AudioParameters& params) {
226 DVLOG(1) << "WebRtcLocalAudioTrack::SetCaptureFormat()"; 229 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()";
227 // If the source is restarted, we might have changed to another capture 230 // If the source is restarted, we might have changed to another capture
228 // thread. 231 // thread.
229 capture_thread_checker_.DetachFromThread(); 232 capture_thread_checker_.DetachFromThread();
230 DCHECK(capture_thread_checker_.CalledOnValidThread()); 233 DCHECK(capture_thread_checker_.CalledOnValidThread());
231 234
232 DCHECK(params.IsValid()); 235 DCHECK(params.IsValid());
233 buffer_->Configure(params); 236 buffer_->Configure(params);
234 237
235 base::AutoLock auto_lock(lock_); 238 base::AutoLock auto_lock(lock_);
236 // Copy |sinks_| to |sinks_to_notify_format_| to notify all the sinks 239 // Copy |sinks_| to |sinks_to_notify_format_| to notify all the sinks
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } 271 }
269 272
270 cricket::AudioRenderer* WebRtcLocalAudioTrack::GetRenderer() { 273 cricket::AudioRenderer* WebRtcLocalAudioTrack::GetRenderer() {
271 return this; 274 return this;
272 } 275 }
273 276
274 std::string WebRtcLocalAudioTrack::kind() const { 277 std::string WebRtcLocalAudioTrack::kind() const {
275 return kAudioTrackKind; 278 return kAudioTrackKind;
276 } 279 }
277 280
278 void WebRtcLocalAudioTrack::AddSink(WebRtcAudioCapturerSink* sink) { 281 void WebRtcLocalAudioTrack::AddSink(MediaStreamAudioSink* sink) {
279 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 282 DCHECK(main_render_thread_checker_.CalledOnValidThread());
280 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()"; 283 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
281 base::AutoLock auto_lock(lock_); 284 base::AutoLock auto_lock(lock_);
282 285
283 // Verify that |sink| is not already added to the list. 286 // Verify that |sink| is not already added to the list.
284 DCHECK(std::find_if( 287 DCHECK(std::find_if(
285 sinks_.begin(), sinks_.end(), 288 sinks_.begin(), sinks_.end(),
286 WebRtcAudioCapturerSinkOwner::WrapsSink(sink)) == sinks_.end()); 289 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)) == sinks_.end());
287 290
288 // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns 291 // Create (and add to the list) a new MediaStreamAudioTrackSink which owns
289 // the |sink| and delagates all calls to the WebRtcAudioCapturerSink 292 // the |sink| and delagates all calls to the MediaStreamAudioSink
290 // interface. 293 // interface.
291 scoped_refptr<WebRtcAudioCapturerSinkOwner> sink_owner( 294 scoped_refptr<MediaStreamAudioTrackSink> sink_owner(
292 new WebRtcAudioCapturerSinkOwner(sink)); 295 new MediaStreamAudioSinkOwner(sink));
293 sinks_.push_back(sink_owner); 296 sinks_.push_back(sink_owner);
294 297
295 // Also push the |sink_owner| to |sinks_to_notify_format_| so that we will 298 // Also push the |sink_owner| to |sinks_to_notify_format_| so that we will
296 // call SetCaptureFormat() on the new sink. 299 // call OnSetFormat() on the new sink.
297 sinks_to_notify_format_.push_back(sink_owner); 300 sinks_to_notify_format_.push_back(sink_owner);
298 } 301 }
299 302
300 void WebRtcLocalAudioTrack::RemoveSink( 303 void WebRtcLocalAudioTrack::RemoveSink(MediaStreamAudioSink* sink) {
301 WebRtcAudioCapturerSink* sink) {
302 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 304 DCHECK(main_render_thread_checker_.CalledOnValidThread());
303 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveSink()"; 305 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveSink()";
304 306
305 base::AutoLock auto_lock(lock_); 307 base::AutoLock auto_lock(lock_);
306 // Remove the item on |tracks_to_notify_format_|. 308 // Remove the item on |tracks_to_notify_format_|.
307 // This has to be done before remove the element in |sinks_| since there it 309 // This has to be done before remove the element in |sinks_| since there it
308 // will clear the delegate. 310 // will clear the delegate.
309 SinkList::iterator it = std::find_if( 311 SinkList::iterator it = std::find_if(
310 sinks_to_notify_format_.begin(), sinks_to_notify_format_.end(), 312 sinks_to_notify_format_.begin(), sinks_to_notify_format_.end(),
311 WebRtcAudioCapturerSinkOwner::WrapsSink(sink)); 313 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink));
312 if (it != sinks_to_notify_format_.end()) 314 if (it != sinks_to_notify_format_.end())
313 sinks_to_notify_format_.erase(it); 315 sinks_to_notify_format_.erase(it);
314 316
315 // Get iterator to the first element for which WrapsSink(sink) returns true. 317 // Get iterator to the first element for which WrapsSink(sink) returns true.
316 it = std::find_if(sinks_.begin(), sinks_.end(), 318 it = std::find_if(sinks_.begin(), sinks_.end(),
317 WebRtcAudioCapturerSinkOwner::WrapsSink(sink)); 319 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink));
318 if (it != sinks_.end()) { 320 if (it != sinks_.end()) {
319 // Clear the delegate to ensure that no more capture callbacks will 321 // Clear the delegate to ensure that no more capture callbacks will
320 // be sent to this sink. Also avoids a possible crash which can happen 322 // be sent to this sink. Also avoids a possible crash which can happen
323 // if this method is called while capturing is active.
324 (*it)->Reset();
325 sinks_.erase(it);
326 }
327 }
328
329 void WebRtcLocalAudioTrack::AddSink(PeerConnectionAudioSink* sink) {
330 DCHECK(main_render_thread_checker_.CalledOnValidThread());
331 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
332 base::AutoLock auto_lock(lock_);
333
334 // Verify that |sink| is not already added to the list.
335 DCHECK(std::find_if(
336 sinks_.begin(), sinks_.end(),
337 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink)) ==
338 sinks_.end());
339
340 // Create (and add to the list) a new MediaStreamAudioTrackSink which owns
341 // the |sink| and delagates all calls to the MediaStreamAudioSink
342 // interface.
343 scoped_refptr<MediaStreamAudioTrackSink> sink_owner(
344 new PeerConnectionAudioSinkOwner(sink));
345 sinks_.push_back(sink_owner);
346
347 // Also push the |sink_owner| to |sinks_to_notify_format_| so that we will
348 // call OnSetFormat() on the new sink.
349 sinks_to_notify_format_.push_back(sink_owner);
350 }
351
352 void WebRtcLocalAudioTrack::RemoveSink(PeerConnectionAudioSink* sink) {
353 DCHECK(main_render_thread_checker_.CalledOnValidThread());
354 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveSink()";
355
356 base::AutoLock auto_lock(lock_);
357 // Remove the item on |tracks_to_notify_format_|.
358 // This has to be done before remove the element in |sinks_| since there it
359 // will clear the delegate.
360 SinkList::iterator it = std::find_if(
361 sinks_to_notify_format_.begin(), sinks_to_notify_format_.end(),
362 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink));
363 if (it != sinks_to_notify_format_.end())
364 sinks_to_notify_format_.erase(it);
365
366 // Get iterator to the first element for which WrapsPeerConnectionSink(sink)
367 // returns true.
368 it = std::find_if(sinks_.begin(), sinks_.end(),
369 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink));
370 if (it != sinks_.end()) {
371 // Clear the delegate to ensure that no more capture callbacks will
372 // be sent to this sink. Also avoids a possible crash which can happen
321 // if this method is called while capturing is active. 373 // if this method is called while capturing is active.
322 (*it)->Reset(); 374 (*it)->Reset();
323 sinks_.erase(it); 375 sinks_.erase(it);
324 } 376 }
325 } 377 }
326 378
327 void WebRtcLocalAudioTrack::Start() { 379 void WebRtcLocalAudioTrack::Start() {
328 DCHECK(main_render_thread_checker_.CalledOnValidThread()); 380 DCHECK(main_render_thread_checker_.CalledOnValidThread());
329 DVLOG(1) << "WebRtcLocalAudioTrack::Start()"; 381 DVLOG(1) << "WebRtcLocalAudioTrack::Start()";
330 if (webaudio_source_.get()) { 382 if (webaudio_source_.get()) {
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
366 sinks_to_notify_format_.clear(); 418 sinks_to_notify_format_.clear();
367 webaudio_source_ = NULL; 419 webaudio_source_ = NULL;
368 capturer_ = NULL; 420 capturer_ = NULL;
369 } 421 }
370 422
371 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) 423 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it)
372 (*it)->Reset(); 424 (*it)->Reset();
373 } 425 }
374 426
375 } // namespace content 427 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_local_audio_track.h ('k') | content/renderer/media/webrtc_local_audio_track_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698