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

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

Powered by Google App Engine
This is Rietveld 408576698