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

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: only allow calling StartAecDump() on one APM. 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 device_info_.device.input.sample_rate) == 180 device_info_.device.input.sample_rate) ==
181 &kValidInputRates[arraysize(kValidInputRates)]) { 181 &kValidInputRates[arraysize(kValidInputRates)]) {
182 DLOG(ERROR) << device_info_.device.input.sample_rate 182 DLOG(ERROR) << device_info_.device.input.sample_rate
183 << " is not a supported input rate."; 183 << " is not a supported input rate.";
184 return false; 184 return false;
185 } 185 }
186 186
187 // Create and configure the default audio capturing source. 187 // Create and configure the default audio capturing source.
188 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id_), 188 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id_),
189 channel_layout, 189 channel_layout,
190 static_cast<float>(device_info_.device.input.sample_rate), 190 static_cast<float>(device_info_.device.input.sample_rate));
191 device_info_.device.input.effects,
192 constraints_);
193 191
194 // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware 192 // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware
195 // information from the capturer. 193 // information from the capturer.
196 if (audio_device_) 194 if (audio_device_)
197 audio_device_->AddAudioCapturer(this); 195 audio_device_->AddAudioCapturer(this);
198 196
199 return true; 197 return true;
200 } 198 }
201 199
202 WebRtcAudioCapturer::WebRtcAudioCapturer( 200 WebRtcAudioCapturer::WebRtcAudioCapturer(
203 int render_view_id, 201 int render_view_id,
204 const StreamDeviceInfo& device_info, 202 const StreamDeviceInfo& device_info,
205 const blink::WebMediaConstraints& constraints, 203 const blink::WebMediaConstraints& constraints,
206 WebRtcAudioDeviceImpl* audio_device) 204 WebRtcAudioDeviceImpl* audio_device)
207 : constraints_(constraints), 205 : constraints_(constraints),
206 audio_processor_(new MediaStreamAudioProcessor(
207 constraints, device_info.device.input.effects, audio_device)),
208 running_(false), 208 running_(false),
209 render_view_id_(render_view_id), 209 render_view_id_(render_view_id),
210 device_info_(device_info), 210 device_info_(device_info),
211 volume_(0), 211 volume_(0),
212 peer_connection_mode_(false), 212 peer_connection_mode_(false),
213 key_pressed_(false), 213 key_pressed_(false),
214 need_audio_processing_(false), 214 need_audio_processing_(false),
215 audio_device_(audio_device) { 215 audio_device_(audio_device) {
216 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; 216 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()";
217 } 217 }
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
254 // Clear the delegate to ensure that no more capture callbacks will 254 // Clear the delegate to ensure that no more capture callbacks will
255 // be sent to this sink. Also avoids a possible crash which can happen 255 // be sent to this sink. Also avoids a possible crash which can happen
256 // if this method is called while capturing is active. 256 // if this method is called while capturing is active.
257 if (removed_item.get()) 257 if (removed_item.get())
258 removed_item->Reset(); 258 removed_item->Reset();
259 } 259 }
260 260
261 void WebRtcAudioCapturer::SetCapturerSource( 261 void WebRtcAudioCapturer::SetCapturerSource(
262 const scoped_refptr<media::AudioCapturerSource>& source, 262 const scoped_refptr<media::AudioCapturerSource>& source,
263 media::ChannelLayout channel_layout, 263 media::ChannelLayout channel_layout,
264 float sample_rate, 264 float sample_rate) {
265 int effects,
266 const blink::WebMediaConstraints& constraints) {
267 DCHECK(thread_checker_.CalledOnValidThread()); 265 DCHECK(thread_checker_.CalledOnValidThread());
268 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," 266 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << ","
269 << "sample_rate=" << sample_rate << ")"; 267 << "sample_rate=" << sample_rate << ")";
270 scoped_refptr<media::AudioCapturerSource> old_source; 268 scoped_refptr<media::AudioCapturerSource> old_source;
271 bool restart_source = false; 269 bool restart_source = false;
272 { 270 {
273 base::AutoLock auto_lock(lock_); 271 base::AutoLock auto_lock(lock_);
274 if (source_.get() == source.get()) 272 if (source_.get() == source.get())
275 return; 273 return;
276 274
(...skipping 10 matching lines...) Expand all
287 old_source->Stop(); 285 old_source->Stop();
288 286
289 // Dispatch the new parameters both to the sink(s) and to the new source, 287 // Dispatch the new parameters both to the sink(s) and to the new source,
290 // also apply the new |constraints|. 288 // also apply the new |constraints|.
291 // The idea is to get rid of any dependency of the microphone parameters 289 // The idea is to get rid of any dependency of the microphone parameters
292 // which would normally be used by default. 290 // which would normally be used by default.
293 // bits_per_sample is always 16 for now. 291 // bits_per_sample is always 16 for now.
294 int buffer_size = GetBufferSize(sample_rate); 292 int buffer_size = GetBufferSize(sample_rate);
295 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 293 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
296 channel_layout, 0, sample_rate, 294 channel_layout, 0, sample_rate,
297 16, buffer_size, effects); 295 16, buffer_size,
298 scoped_refptr<MediaStreamAudioProcessor> new_audio_processor( 296 device_info_.device.input.effects);
299 new MediaStreamAudioProcessor(params, constraints, effects, 297
300 audio_device_));
301 { 298 {
302 base::AutoLock auto_lock(lock_); 299 base::AutoLock auto_lock(lock_);
303 audio_processor_ = new_audio_processor; 300 // Notify the |audio_processor_| of the new format.
304 need_audio_processing_ = NeedsAudioProcessing(constraints, effects); 301 audio_processor_->OnCaptureFormatChanged(params);
305 302
303 need_audio_processing_ = NeedsAudioProcessing(
304 constraints_, device_info_.device.input.effects);
306 // Notify all tracks about the new format. 305 // Notify all tracks about the new format.
307 tracks_.TagAll(); 306 tracks_.TagAll();
308 } 307 }
309 308
310 if (source.get()) 309 if (source.get())
311 source->Initialize(params, this, session_id()); 310 source->Initialize(params, this, session_id());
312 311
313 if (restart_source) 312 if (restart_source)
314 Start(); 313 Start();
315 } 314 }
(...skipping 22 matching lines...) Expand all
338 // Do nothing if the current buffer size is the WebRtc native buffer size. 337 // Do nothing if the current buffer size is the WebRtc native buffer size.
339 if (GetBufferSize(input_params.sample_rate()) == 338 if (GetBufferSize(input_params.sample_rate()) ==
340 input_params.frames_per_buffer()) { 339 input_params.frames_per_buffer()) {
341 return; 340 return;
342 } 341 }
343 342
344 // Create a new audio stream as source which will open the hardware using 343 // Create a new audio stream as source which will open the hardware using
345 // WebRtc native buffer size. 344 // WebRtc native buffer size.
346 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id), 345 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id),
347 input_params.channel_layout(), 346 input_params.channel_layout(),
348 static_cast<float>(input_params.sample_rate()), 347 static_cast<float>(input_params.sample_rate()));
349 input_params.effects(),
350 constraints_);
351 } 348 }
352 349
353 void WebRtcAudioCapturer::Start() { 350 void WebRtcAudioCapturer::Start() {
351 DCHECK(thread_checker_.CalledOnValidThread());
354 DVLOG(1) << "WebRtcAudioCapturer::Start()"; 352 DVLOG(1) << "WebRtcAudioCapturer::Start()";
355 base::AutoLock auto_lock(lock_); 353 base::AutoLock auto_lock(lock_);
356 if (running_ || !source_) 354 if (running_ || !source_)
357 return; 355 return;
358 356
359 // Start the data source, i.e., start capturing data from the current source. 357 // Start the data source, i.e., start capturing data from the current source.
360 // We need to set the AGC control before starting the stream. 358 // We need to set the AGC control before starting the stream.
361 source_->SetAutomaticGainControl(true); 359 source_->SetAutomaticGainControl(true);
362 source_->Start(); 360 source_->Start();
363 running_ = true; 361 running_ = true;
364 } 362 }
365 363
366 void WebRtcAudioCapturer::Stop() { 364 void WebRtcAudioCapturer::Stop() {
365 DCHECK(thread_checker_.CalledOnValidThread());
367 DVLOG(1) << "WebRtcAudioCapturer::Stop()"; 366 DVLOG(1) << "WebRtcAudioCapturer::Stop()";
368 scoped_refptr<media::AudioCapturerSource> source; 367 scoped_refptr<media::AudioCapturerSource> source;
369 TrackList::ItemList tracks; 368 TrackList::ItemList tracks;
370 { 369 {
371 base::AutoLock auto_lock(lock_); 370 base::AutoLock auto_lock(lock_);
372 if (!running_) 371 if (!running_)
373 return; 372 return;
374 373
375 source = source_; 374 source = source_;
376 tracks = tracks_.Items(); 375 tracks = tracks_.Items();
377 tracks_.Clear(); 376 tracks_.Clear();
378 running_ = false; 377 running_ = false;
379 } 378 }
380 379
381 // Remove the capturer object from the WebRtcAudioDeviceImpl. 380 // Remove the capturer object from the WebRtcAudioDeviceImpl.
382 if (audio_device_) 381 if (audio_device_)
383 audio_device_->RemoveAudioCapturer(this); 382 audio_device_->RemoveAudioCapturer(this);
384 383
384 // Stop the Aec dump.
385 StopAecDump();
386
385 for (TrackList::ItemList::const_iterator it = tracks.begin(); 387 for (TrackList::ItemList::const_iterator it = tracks.begin();
386 it != tracks.end(); 388 it != tracks.end();
387 ++it) { 389 ++it) {
388 (*it)->Stop(); 390 (*it)->Stop();
389 } 391 }
390 392
391 if (source.get()) 393 if (source.get())
392 source->Stop(); 394 source->Stop();
393 } 395 }
394 396
(...skipping 30 matching lines...) Expand all
425 // allows the user to set a scaling that is higher than 100%. It means that 427 // allows the user to set a scaling that is higher than 100%. It means that
426 // even if the reported maximum levels is N, the actual microphone level can 428 // even if the reported maximum levels is N, the actual microphone level can
427 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x. 429 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x.
428 DCHECK_LE(volume, 1.6); 430 DCHECK_LE(volume, 1.6);
429 #endif 431 #endif
430 432
431 TrackList::ItemList tracks; 433 TrackList::ItemList tracks;
432 TrackList::ItemList tracks_to_notify_format; 434 TrackList::ItemList tracks_to_notify_format;
433 int current_volume = 0; 435 int current_volume = 0;
434 base::TimeDelta audio_delay; 436 base::TimeDelta audio_delay;
435 scoped_refptr<MediaStreamAudioProcessor> audio_processor;
436 bool need_audio_processing = true; 437 bool need_audio_processing = true;
437 { 438 {
438 base::AutoLock auto_lock(lock_); 439 base::AutoLock auto_lock(lock_);
439 if (!running_) 440 if (!running_)
440 return; 441 return;
441 442
442 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the 443 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the
443 // webrtc::VoiceEngine. webrtc::VoiceEngine will handle the case when the 444 // webrtc::VoiceEngine. webrtc::VoiceEngine will handle the case when the
444 // volume is higher than 255. 445 // volume is higher than 255.
445 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5); 446 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5);
446 current_volume = volume_; 447 current_volume = volume_;
447 audio_delay = base::TimeDelta::FromMilliseconds(audio_delay_milliseconds); 448 audio_delay = base::TimeDelta::FromMilliseconds(audio_delay_milliseconds);
448 audio_delay_ = audio_delay; 449 audio_delay_ = audio_delay;
449 key_pressed_ = key_pressed; 450 key_pressed_ = key_pressed;
450 tracks = tracks_.Items(); 451 tracks = tracks_.Items();
451 tracks_.RetrieveAndClearTags(&tracks_to_notify_format); 452 tracks_.RetrieveAndClearTags(&tracks_to_notify_format);
452 audio_processor = audio_processor_;
453 453
454 // Set the flag to turn on the audio processing in PeerConnection level. 454 // Set the flag to turn on the audio processing in PeerConnection level.
455 // Note that, we turn off the audio processing in PeerConnection if the 455 // Note that, we turn off the audio processing in PeerConnection if the
456 // processor has already processed the data. 456 // processor has already processed the data.
457 need_audio_processing = need_audio_processing_ ? 457 need_audio_processing = need_audio_processing_ ?
458 !audio_processor->has_audio_processing() : false; 458 !audio_processor_->has_audio_processing() : false;
459 } 459 }
460 460
461 DCHECK(audio_processor->InputFormat().IsValid()); 461 DCHECK(audio_processor_->InputFormat().IsValid());
462 DCHECK_EQ(audio_source->channels(), 462 DCHECK_EQ(audio_source->channels(),
463 audio_processor->InputFormat().channels()); 463 audio_processor_->InputFormat().channels());
464 DCHECK_EQ(audio_source->frames(), 464 DCHECK_EQ(audio_source->frames(),
465 audio_processor->InputFormat().frames_per_buffer()); 465 audio_processor_->InputFormat().frames_per_buffer());
466 466
467 // Notify the tracks on when the format changes. This will do nothing if 467 // Notify the tracks on when the format changes. This will do nothing if
468 // |tracks_to_notify_format| is empty. 468 // |tracks_to_notify_format| is empty.
469 media::AudioParameters output_params = audio_processor_->OutputFormat(); 469 media::AudioParameters output_params = audio_processor_->OutputFormat();
470 for (TrackList::ItemList::const_iterator it = tracks_to_notify_format.begin(); 470 for (TrackList::ItemList::const_iterator it = tracks_to_notify_format.begin();
471 it != tracks_to_notify_format.end(); ++it) { 471 it != tracks_to_notify_format.end(); ++it) {
472 (*it)->OnSetFormat(output_params); 472 (*it)->OnSetFormat(output_params);
473 } 473 }
474 474
475 // Push the data to the processor for processing. 475 // Push the data to the processor for processing.
476 audio_processor->PushCaptureData(audio_source); 476 audio_processor_->PushCaptureData(audio_source);
477 477
478 // Process and consume the data in the processor until there is not enough 478 // Process and consume the data in the processor until there is not enough
479 // data in the processor. 479 // data in the processor.
480 int16* output = NULL; 480 int16* output = NULL;
481 int new_volume = 0; 481 int new_volume = 0;
482 while (audio_processor->ProcessAndConsumeData( 482 while (audio_processor_->ProcessAndConsumeData(
483 audio_delay, current_volume, key_pressed, &new_volume, &output)) { 483 audio_delay, current_volume, key_pressed, &new_volume, &output)) {
484 // Feed the post-processed data to the tracks. 484 // Feed the post-processed data to the tracks.
485 for (TrackList::ItemList::const_iterator it = tracks.begin(); 485 for (TrackList::ItemList::const_iterator it = tracks.begin();
486 it != tracks.end(); ++it) { 486 it != tracks.end(); ++it) {
487 (*it)->Capture(output, audio_delay, current_volume, key_pressed, 487 (*it)->Capture(output, audio_delay, current_volume, key_pressed,
488 need_audio_processing); 488 need_audio_processing);
489 } 489 }
490 490
491 if (new_volume) { 491 if (new_volume) {
492 SetVolume(new_volume); 492 SetVolume(new_volume);
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
554 *delay = audio_delay_; 554 *delay = audio_delay_;
555 *volume = volume_; 555 *volume = volume_;
556 *key_pressed = key_pressed_; 556 *key_pressed = key_pressed_;
557 } 557 }
558 558
559 void WebRtcAudioCapturer::SetCapturerSourceForTesting( 559 void WebRtcAudioCapturer::SetCapturerSourceForTesting(
560 const scoped_refptr<media::AudioCapturerSource>& source, 560 const scoped_refptr<media::AudioCapturerSource>& source,
561 media::AudioParameters params) { 561 media::AudioParameters params) {
562 // Create a new audio stream as source which uses the new source. 562 // Create a new audio stream as source which uses the new source.
563 SetCapturerSource(source, params.channel_layout(), 563 SetCapturerSource(source, params.channel_layout(),
564 static_cast<float>(params.sample_rate()), 564 static_cast<float>(params.sample_rate()));
565 params.effects(), 565 }
566 constraints_); 566
567 void WebRtcAudioCapturer::StartAecDump(
568 const base::PlatformFile& aec_dump_file) {
569 DCHECK(thread_checker_.CalledOnValidThread());
570 DCHECK_NE(aec_dump_file, base::kInvalidPlatformFileValue);
571 audio_processor_->StartAecDump(aec_dump_file);
572 }
573
574 void WebRtcAudioCapturer::StopAecDump() {
575 DCHECK(thread_checker_.CalledOnValidThread());
576 audio_processor_->StopAecDump();
567 } 577 }
568 578
569 } // namespace content 579 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698