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

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

Issue 187913002: Support the Aec dump for the APM in chrome (Closed) Base URL: http://git.chromium.org/chromium/src.git@master
Patch Set: minor fix to one comment. Created 6 years, 9 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
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/strings/string_util.h" 10 #include "base/strings/string_util.h"
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
187 device_info_.device.input.sample_rate) == 187 device_info_.device.input.sample_rate) ==
188 &kValidInputRates[arraysize(kValidInputRates)]) { 188 &kValidInputRates[arraysize(kValidInputRates)]) {
189 DLOG(ERROR) << device_info_.device.input.sample_rate 189 DLOG(ERROR) << device_info_.device.input.sample_rate
190 << " is not a supported input rate."; 190 << " is not a supported input rate.";
191 return false; 191 return false;
192 } 192 }
193 193
194 // Create and configure the default audio capturing source. 194 // Create and configure the default audio capturing source.
195 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id_), 195 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id_),
196 channel_layout, 196 channel_layout,
197 static_cast<float>(device_info_.device.input.sample_rate), 197 static_cast<float>(device_info_.device.input.sample_rate));
198 device_info_.device.input.effects,
199 constraints_);
200 198
201 // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware 199 // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware
202 // information from the capturer. 200 // information from the capturer.
203 if (audio_device_) 201 if (audio_device_)
204 audio_device_->AddAudioCapturer(this); 202 audio_device_->AddAudioCapturer(this);
205 203
206 return true; 204 return true;
207 } 205 }
208 206
209 WebRtcAudioCapturer::WebRtcAudioCapturer( 207 WebRtcAudioCapturer::WebRtcAudioCapturer(
210 int render_view_id, 208 int render_view_id,
211 const StreamDeviceInfo& device_info, 209 const StreamDeviceInfo& device_info,
212 const blink::WebMediaConstraints& constraints, 210 const blink::WebMediaConstraints& constraints,
213 WebRtcAudioDeviceImpl* audio_device) 211 WebRtcAudioDeviceImpl* audio_device)
214 : constraints_(constraints), 212 : constraints_(constraints),
213 audio_processor_(
214 new talk_base::RefCountedObject<MediaStreamAudioProcessor>(
215 constraints, device_info.device.input.effects, audio_device)),
215 running_(false), 216 running_(false),
216 render_view_id_(render_view_id), 217 render_view_id_(render_view_id),
217 device_info_(device_info), 218 device_info_(device_info),
218 volume_(0), 219 volume_(0),
219 peer_connection_mode_(false), 220 peer_connection_mode_(false),
220 key_pressed_(false), 221 key_pressed_(false),
221 need_audio_processing_(false), 222 need_audio_processing_(false),
222 audio_device_(audio_device) { 223 audio_device_(audio_device) {
223 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; 224 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()";
224 } 225 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
261 // Clear the delegate to ensure that no more capture callbacks will 262 // Clear the delegate to ensure that no more capture callbacks will
262 // be sent to this sink. Also avoids a possible crash which can happen 263 // be sent to this sink. Also avoids a possible crash which can happen
263 // if this method is called while capturing is active. 264 // if this method is called while capturing is active.
264 if (removed_item.get()) 265 if (removed_item.get())
265 removed_item->Reset(); 266 removed_item->Reset();
266 } 267 }
267 268
268 void WebRtcAudioCapturer::SetCapturerSource( 269 void WebRtcAudioCapturer::SetCapturerSource(
269 const scoped_refptr<media::AudioCapturerSource>& source, 270 const scoped_refptr<media::AudioCapturerSource>& source,
270 media::ChannelLayout channel_layout, 271 media::ChannelLayout channel_layout,
271 float sample_rate, 272 float sample_rate) {
272 int effects,
273 const blink::WebMediaConstraints& constraints) {
274 DCHECK(thread_checker_.CalledOnValidThread()); 273 DCHECK(thread_checker_.CalledOnValidThread());
275 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," 274 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << ","
276 << "sample_rate=" << sample_rate << ")"; 275 << "sample_rate=" << sample_rate << ")";
277 scoped_refptr<media::AudioCapturerSource> old_source; 276 scoped_refptr<media::AudioCapturerSource> old_source;
278 bool restart_source = false; 277 bool restart_source = false;
279 { 278 {
280 base::AutoLock auto_lock(lock_); 279 base::AutoLock auto_lock(lock_);
281 if (source_.get() == source.get()) 280 if (source_.get() == source.get())
282 return; 281 return;
283 282
(...skipping 10 matching lines...) Expand all
294 old_source->Stop(); 293 old_source->Stop();
295 294
296 // Dispatch the new parameters both to the sink(s) and to the new source, 295 // Dispatch the new parameters both to the sink(s) and to the new source,
297 // also apply the new |constraints|. 296 // also apply the new |constraints|.
298 // The idea is to get rid of any dependency of the microphone parameters 297 // The idea is to get rid of any dependency of the microphone parameters
299 // which would normally be used by default. 298 // which would normally be used by default.
300 // bits_per_sample is always 16 for now. 299 // bits_per_sample is always 16 for now.
301 int buffer_size = GetBufferSize(sample_rate); 300 int buffer_size = GetBufferSize(sample_rate);
302 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 301 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
303 channel_layout, 0, sample_rate, 302 channel_layout, 0, sample_rate,
304 16, buffer_size, effects); 303 16, buffer_size,
305 scoped_refptr<MediaStreamAudioProcessor> new_audio_processor( 304 device_info_.device.input.effects);
306 new talk_base::RefCountedObject<MediaStreamAudioProcessor>( 305
307 params, constraints, effects, audio_device_));
308 { 306 {
309 base::AutoLock auto_lock(lock_); 307 base::AutoLock auto_lock(lock_);
310 audio_processor_ = new_audio_processor; 308 // Notify the |audio_processor_| of the new format.
311 need_audio_processing_ = NeedsAudioProcessing(constraints, effects); 309 audio_processor_->OnCaptureFormatChanged(params);
312 310
311 need_audio_processing_ = NeedsAudioProcessing(
312 constraints_, device_info_.device.input.effects);
313 // Notify all tracks about the new format. 313 // Notify all tracks about the new format.
314 tracks_.TagAll(); 314 tracks_.TagAll();
315 } 315 }
316 316
317 if (source.get()) 317 if (source.get())
318 source->Initialize(params, this, session_id()); 318 source->Initialize(params, this, session_id());
319 319
320 if (restart_source) 320 if (restart_source)
321 Start(); 321 Start();
322 } 322 }
(...skipping 22 matching lines...) Expand all
345 // Do nothing if the current buffer size is the WebRtc native buffer size. 345 // Do nothing if the current buffer size is the WebRtc native buffer size.
346 if (GetBufferSize(input_params.sample_rate()) == 346 if (GetBufferSize(input_params.sample_rate()) ==
347 input_params.frames_per_buffer()) { 347 input_params.frames_per_buffer()) {
348 return; 348 return;
349 } 349 }
350 350
351 // Create a new audio stream as source which will open the hardware using 351 // Create a new audio stream as source which will open the hardware using
352 // WebRtc native buffer size. 352 // WebRtc native buffer size.
353 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id), 353 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id),
354 input_params.channel_layout(), 354 input_params.channel_layout(),
355 static_cast<float>(input_params.sample_rate()), 355 static_cast<float>(input_params.sample_rate()));
356 input_params.effects(),
357 constraints_);
358 } 356 }
359 357
360 void WebRtcAudioCapturer::Start() { 358 void WebRtcAudioCapturer::Start() {
359 DCHECK(thread_checker_.CalledOnValidThread());
361 DVLOG(1) << "WebRtcAudioCapturer::Start()"; 360 DVLOG(1) << "WebRtcAudioCapturer::Start()";
362 base::AutoLock auto_lock(lock_); 361 base::AutoLock auto_lock(lock_);
363 if (running_ || !source_) 362 if (running_ || !source_)
364 return; 363 return;
365 364
366 // Start the data source, i.e., start capturing data from the current source. 365 // Start the data source, i.e., start capturing data from the current source.
367 // We need to set the AGC control before starting the stream. 366 // We need to set the AGC control before starting the stream.
368 source_->SetAutomaticGainControl(true); 367 source_->SetAutomaticGainControl(true);
369 source_->Start(); 368 source_->Start();
370 running_ = true; 369 running_ = true;
371 } 370 }
372 371
373 void WebRtcAudioCapturer::Stop() { 372 void WebRtcAudioCapturer::Stop() {
373 DCHECK(thread_checker_.CalledOnValidThread());
374 DVLOG(1) << "WebRtcAudioCapturer::Stop()"; 374 DVLOG(1) << "WebRtcAudioCapturer::Stop()";
375 scoped_refptr<media::AudioCapturerSource> source; 375 scoped_refptr<media::AudioCapturerSource> source;
376 TrackList::ItemList tracks; 376 TrackList::ItemList tracks;
377 { 377 {
378 base::AutoLock auto_lock(lock_); 378 base::AutoLock auto_lock(lock_);
379 if (!running_) 379 if (!running_)
380 return; 380 return;
381 381
382 source = source_; 382 source = source_;
383 tracks = tracks_.Items(); 383 tracks = tracks_.Items();
384 tracks_.Clear(); 384 tracks_.Clear();
385 running_ = false; 385 running_ = false;
386 } 386 }
387 387
388 // Remove the capturer object from the WebRtcAudioDeviceImpl. 388 // Remove the capturer object from the WebRtcAudioDeviceImpl.
389 if (audio_device_) 389 if (audio_device_)
390 audio_device_->RemoveAudioCapturer(this); 390 audio_device_->RemoveAudioCapturer(this);
391 391
392 // Stop the Aec dump.
393 StopAecDump();
394
392 for (TrackList::ItemList::const_iterator it = tracks.begin(); 395 for (TrackList::ItemList::const_iterator it = tracks.begin();
393 it != tracks.end(); 396 it != tracks.end();
394 ++it) { 397 ++it) {
395 (*it)->Stop(); 398 (*it)->Stop();
396 } 399 }
397 400
398 if (source.get()) 401 if (source.get())
399 source->Stop(); 402 source->Stop();
400 } 403 }
401 404
(...skipping 30 matching lines...) Expand all
432 // allows the user to set a scaling that is higher than 100%. It means that 435 // allows the user to set a scaling that is higher than 100%. It means that
433 // even if the reported maximum levels is N, the actual microphone level can 436 // even if the reported maximum levels is N, the actual microphone level can
434 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x. 437 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x.
435 DCHECK_LE(volume, 1.6); 438 DCHECK_LE(volume, 1.6);
436 #endif 439 #endif
437 440
438 TrackList::ItemList tracks; 441 TrackList::ItemList tracks;
439 TrackList::ItemList tracks_to_notify_format; 442 TrackList::ItemList tracks_to_notify_format;
440 int current_volume = 0; 443 int current_volume = 0;
441 base::TimeDelta audio_delay; 444 base::TimeDelta audio_delay;
442 scoped_refptr<MediaStreamAudioProcessor> audio_processor;
443 bool need_audio_processing = true; 445 bool need_audio_processing = true;
444 { 446 {
445 base::AutoLock auto_lock(lock_); 447 base::AutoLock auto_lock(lock_);
446 if (!running_) 448 if (!running_)
447 return; 449 return;
448 450
449 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the 451 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the
450 // webrtc::VoiceEngine. webrtc::VoiceEngine will handle the case when the 452 // webrtc::VoiceEngine. webrtc::VoiceEngine will handle the case when the
451 // volume is higher than 255. 453 // volume is higher than 255.
452 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5); 454 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5);
453 current_volume = volume_; 455 current_volume = volume_;
454 audio_delay = base::TimeDelta::FromMilliseconds(audio_delay_milliseconds); 456 audio_delay = base::TimeDelta::FromMilliseconds(audio_delay_milliseconds);
455 audio_delay_ = audio_delay; 457 audio_delay_ = audio_delay;
456 key_pressed_ = key_pressed; 458 key_pressed_ = key_pressed;
457 tracks = tracks_.Items(); 459 tracks = tracks_.Items();
458 tracks_.RetrieveAndClearTags(&tracks_to_notify_format); 460 tracks_.RetrieveAndClearTags(&tracks_to_notify_format);
459 audio_processor = audio_processor_;
460 461
461 // Set the flag to turn on the audio processing in PeerConnection level. 462 // Set the flag to turn on the audio processing in PeerConnection level.
462 // Note that, we turn off the audio processing in PeerConnection if the 463 // Note that, we turn off the audio processing in PeerConnection if the
463 // processor has already processed the data. 464 // processor has already processed the data.
464 need_audio_processing = need_audio_processing_ ? 465 need_audio_processing = need_audio_processing_ ?
465 !audio_processor->has_audio_processing() : false; 466 !audio_processor_->has_audio_processing() : false;
466 } 467 }
467 468
468 DCHECK(audio_processor->InputFormat().IsValid()); 469 DCHECK(audio_processor_->InputFormat().IsValid());
469 DCHECK_EQ(audio_source->channels(), 470 DCHECK_EQ(audio_source->channels(),
470 audio_processor->InputFormat().channels()); 471 audio_processor_->InputFormat().channels());
471 DCHECK_EQ(audio_source->frames(), 472 DCHECK_EQ(audio_source->frames(),
472 audio_processor->InputFormat().frames_per_buffer()); 473 audio_processor_->InputFormat().frames_per_buffer());
473 474
474 // Notify the tracks on when the format changes. This will do nothing if 475 // Notify the tracks on when the format changes. This will do nothing if
475 // |tracks_to_notify_format| is empty. 476 // |tracks_to_notify_format| is empty.
476 media::AudioParameters output_params = audio_processor->OutputFormat(); 477 media::AudioParameters output_params = audio_processor_->OutputFormat();
477 for (TrackList::ItemList::const_iterator it = tracks_to_notify_format.begin(); 478 for (TrackList::ItemList::const_iterator it = tracks_to_notify_format.begin();
478 it != tracks_to_notify_format.end(); ++it) { 479 it != tracks_to_notify_format.end(); ++it) {
479 (*it)->OnSetFormat(output_params); 480 (*it)->OnSetFormat(output_params);
480 (*it)->SetAudioProcessor(audio_processor); 481 (*it)->SetAudioProcessor(audio_processor_);
481 } 482 }
482 483
483 // Push the data to the processor for processing. 484 // Push the data to the processor for processing.
484 audio_processor->PushCaptureData(audio_source); 485 audio_processor_->PushCaptureData(audio_source);
485 486
486 // Process and consume the data in the processor until there is not enough 487 // Process and consume the data in the processor until there is not enough
487 // data in the processor. 488 // data in the processor.
488 int16* output = NULL; 489 int16* output = NULL;
489 int new_volume = 0; 490 int new_volume = 0;
490 while (audio_processor->ProcessAndConsumeData( 491 while (audio_processor_->ProcessAndConsumeData(
491 audio_delay, current_volume, key_pressed, &new_volume, &output)) { 492 audio_delay, current_volume, key_pressed, &new_volume, &output)) {
492 // Feed the post-processed data to the tracks. 493 // Feed the post-processed data to the tracks.
493 for (TrackList::ItemList::const_iterator it = tracks.begin(); 494 for (TrackList::ItemList::const_iterator it = tracks.begin();
494 it != tracks.end(); ++it) { 495 it != tracks.end(); ++it) {
495 (*it)->Capture(output, audio_delay, current_volume, key_pressed, 496 (*it)->Capture(output, audio_delay, current_volume, key_pressed,
496 need_audio_processing); 497 need_audio_processing);
497 } 498 }
498 499
499 if (new_volume) { 500 if (new_volume) {
500 SetVolume(new_volume); 501 SetVolume(new_volume);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
562 *delay = audio_delay_; 563 *delay = audio_delay_;
563 *volume = volume_; 564 *volume = volume_;
564 *key_pressed = key_pressed_; 565 *key_pressed = key_pressed_;
565 } 566 }
566 567
567 void WebRtcAudioCapturer::SetCapturerSourceForTesting( 568 void WebRtcAudioCapturer::SetCapturerSourceForTesting(
568 const scoped_refptr<media::AudioCapturerSource>& source, 569 const scoped_refptr<media::AudioCapturerSource>& source,
569 media::AudioParameters params) { 570 media::AudioParameters params) {
570 // Create a new audio stream as source which uses the new source. 571 // Create a new audio stream as source which uses the new source.
571 SetCapturerSource(source, params.channel_layout(), 572 SetCapturerSource(source, params.channel_layout(),
572 static_cast<float>(params.sample_rate()), 573 static_cast<float>(params.sample_rate()));
573 params.effects(), 574 }
574 constraints_); 575
576 void WebRtcAudioCapturer::StartAecDump(
577 const base::PlatformFile& aec_dump_file) {
578 DCHECK(thread_checker_.CalledOnValidThread());
579 DCHECK_NE(aec_dump_file, base::kInvalidPlatformFileValue);
580 audio_processor_->StartAecDump(aec_dump_file);
581 }
582
583 void WebRtcAudioCapturer::StopAecDump() {
584 DCHECK(thread_checker_.CalledOnValidThread());
585 audio_processor_->StopAecDump();
575 } 586 }
576 587
577 } // namespace content 588 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_capturer.h ('k') | content/renderer/media/webrtc_audio_device_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698