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

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

Issue 671793004: Clean up the media stream audio track code (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rebased Created 6 years, 1 month 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 29 matching lines...) Expand all
40 } // namespace 40 } // namespace
41 41
42 // Reference counted container of WebRtcLocalAudioTrack delegate. 42 // Reference counted container of WebRtcLocalAudioTrack delegate.
43 // TODO(xians): Switch to MediaStreamAudioSinkOwner. 43 // TODO(xians): Switch to MediaStreamAudioSinkOwner.
44 class WebRtcAudioCapturer::TrackOwner 44 class WebRtcAudioCapturer::TrackOwner
45 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> { 45 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> {
46 public: 46 public:
47 explicit TrackOwner(WebRtcLocalAudioTrack* track) 47 explicit TrackOwner(WebRtcLocalAudioTrack* track)
48 : delegate_(track) {} 48 : delegate_(track) {}
49 49
50 void Capture(const int16* audio_data, 50 void Capture(const int16* audio_data, bool force_report_nonzero_energy) {
51 base::TimeDelta delay,
52 double volume,
53 bool key_pressed,
54 bool need_audio_processing,
55 bool force_report_nonzero_energy) {
56 base::AutoLock lock(lock_); 51 base::AutoLock lock(lock_);
57 if (delegate_) { 52 if (delegate_) {
58 delegate_->Capture(audio_data, 53 delegate_->Capture(audio_data, force_report_nonzero_energy);
59 delay,
60 volume,
61 key_pressed,
62 need_audio_processing,
63 force_report_nonzero_energy);
64 } 54 }
65 } 55 }
66 56
67 void OnSetFormat(const media::AudioParameters& params) { 57 void OnSetFormat(const media::AudioParameters& params) {
68 base::AutoLock lock(lock_); 58 base::AutoLock lock(lock_);
69 if (delegate_) 59 if (delegate_)
70 delegate_->OnSetFormat(params); 60 delegate_->OnSetFormat(params);
71 } 61 }
72 62
73 void SetAudioProcessor( 63 void SetAudioProcessor(
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
163 if (!audio_constraints.IsValid()) 153 if (!audio_constraints.IsValid())
164 return false; 154 return false;
165 155
166 media::ChannelLayout channel_layout = static_cast<media::ChannelLayout>( 156 media::ChannelLayout channel_layout = static_cast<media::ChannelLayout>(
167 device_info_.device.input.channel_layout); 157 device_info_.device.input.channel_layout);
168 158
169 // If KEYBOARD_MIC effect is set, change the layout to the corresponding 159 // If KEYBOARD_MIC effect is set, change the layout to the corresponding
170 // layout that includes the keyboard mic. 160 // layout that includes the keyboard mic.
171 if ((device_info_.device.input.effects & 161 if ((device_info_.device.input.effects &
172 media::AudioParameters::KEYBOARD_MIC) && 162 media::AudioParameters::KEYBOARD_MIC) &&
173 MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled() &&
174 audio_constraints.GetProperty( 163 audio_constraints.GetProperty(
175 MediaAudioConstraints::kGoogExperimentalNoiseSuppression)) { 164 MediaAudioConstraints::kGoogExperimentalNoiseSuppression)) {
176 if (channel_layout == media::CHANNEL_LAYOUT_STEREO) { 165 if (channel_layout == media::CHANNEL_LAYOUT_STEREO) {
177 channel_layout = media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC; 166 channel_layout = media::CHANNEL_LAYOUT_STEREO_AND_KEYBOARD_MIC;
178 DVLOG(1) << "Changed stereo layout to stereo + keyboard mic layout due " 167 DVLOG(1) << "Changed stereo layout to stereo + keyboard mic layout due "
179 << "to KEYBOARD_MIC effect."; 168 << "to KEYBOARD_MIC effect.";
180 } else { 169 } else {
181 DVLOG(1) << "KEYBOARD_MIC effect ignored, not compatible with layout " 170 DVLOG(1) << "KEYBOARD_MIC effect ignored, not compatible with layout "
182 << channel_layout; 171 << channel_layout;
183 } 172 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 : constraints_(constraints), 218 : constraints_(constraints),
230 audio_processor_(new rtc::RefCountedObject<MediaStreamAudioProcessor>( 219 audio_processor_(new rtc::RefCountedObject<MediaStreamAudioProcessor>(
231 constraints, 220 constraints,
232 device_info.device.input.effects, 221 device_info.device.input.effects,
233 audio_device)), 222 audio_device)),
234 running_(false), 223 running_(false),
235 render_view_id_(render_view_id), 224 render_view_id_(render_view_id),
236 device_info_(device_info), 225 device_info_(device_info),
237 volume_(0), 226 volume_(0),
238 peer_connection_mode_(false), 227 peer_connection_mode_(false),
239 key_pressed_(false),
240 need_audio_processing_(false),
241 audio_device_(audio_device), 228 audio_device_(audio_device),
242 audio_source_(audio_source) { 229 audio_source_(audio_source) {
243 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; 230 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()";
244 } 231 }
245 232
246 WebRtcAudioCapturer::~WebRtcAudioCapturer() { 233 WebRtcAudioCapturer::~WebRtcAudioCapturer() {
247 DCHECK(thread_checker_.CalledOnValidThread()); 234 DCHECK(thread_checker_.CalledOnValidThread());
248 DCHECK(tracks_.IsEmpty()); 235 DCHECK(tracks_.IsEmpty());
249 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; 236 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()";
250 Stop(); 237 Stop();
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, 314 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY,
328 channel_layout, sample_rate, 315 channel_layout, sample_rate,
329 16, buffer_size, 316 16, buffer_size,
330 device_info_.device.input.effects); 317 device_info_.device.input.effects);
331 318
332 { 319 {
333 base::AutoLock auto_lock(lock_); 320 base::AutoLock auto_lock(lock_);
334 // Notify the |audio_processor_| of the new format. 321 // Notify the |audio_processor_| of the new format.
335 audio_processor_->OnCaptureFormatChanged(params); 322 audio_processor_->OnCaptureFormatChanged(params);
336 323
337 MediaAudioConstraints audio_constraints(constraints_,
338 device_info_.device.input.effects);
339 need_audio_processing_ = audio_constraints.NeedsAudioProcessing();
340 // Notify all tracks about the new format. 324 // Notify all tracks about the new format.
341 tracks_.TagAll(); 325 tracks_.TagAll();
342 } 326 }
343 327
344 if (source.get()) 328 if (source.get())
345 source->Initialize(params, this, session_id()); 329 source->Initialize(params, this, session_id());
346 330
347 Start(); 331 Start();
348 } 332 }
349 333
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
461 // allows the user to set a scaling that is higher than 100%. It means that 445 // allows the user to set a scaling that is higher than 100%. It means that
462 // even if the reported maximum levels is N, the actual microphone level can 446 // even if the reported maximum levels is N, the actual microphone level can
463 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x. 447 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x.
464 DCHECK_LE(volume, 1.6); 448 DCHECK_LE(volume, 1.6);
465 #endif 449 #endif
466 450
467 TrackList::ItemList tracks; 451 TrackList::ItemList tracks;
468 TrackList::ItemList tracks_to_notify_format; 452 TrackList::ItemList tracks_to_notify_format;
469 int current_volume = 0; 453 int current_volume = 0;
470 base::TimeDelta audio_delay; 454 base::TimeDelta audio_delay;
471 bool need_audio_processing = true;
472 { 455 {
473 base::AutoLock auto_lock(lock_); 456 base::AutoLock auto_lock(lock_);
474 if (!running_) 457 if (!running_)
475 return; 458 return;
476 459
477 // Map internal volume range of [0.0, 1.0] into [0, 255] used by AGC. 460 // Map internal volume range of [0.0, 1.0] into [0, 255] used by AGC.
478 // The volume can be higher than 255 on Linux, and it will be cropped to 461 // The volume can be higher than 255 on Linux, and it will be cropped to
479 // 255 since AGC does not allow values out of range. 462 // 255 since AGC does not allow values out of range.
480 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5); 463 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5);
481 current_volume = volume_ > MaxVolume() ? MaxVolume() : volume_; 464 current_volume = volume_ > MaxVolume() ? MaxVolume() : volume_;
482 audio_delay = base::TimeDelta::FromMilliseconds(audio_delay_milliseconds); 465 audio_delay = base::TimeDelta::FromMilliseconds(audio_delay_milliseconds);
483 audio_delay_ = audio_delay;
484 key_pressed_ = key_pressed;
485 tracks = tracks_.Items(); 466 tracks = tracks_.Items();
486 tracks_.RetrieveAndClearTags(&tracks_to_notify_format); 467 tracks_.RetrieveAndClearTags(&tracks_to_notify_format);
487
488 // Set the flag to turn on the audio processing in PeerConnection level.
489 // Note that, we turn off the audio processing in PeerConnection if the
490 // processor has already processed the data.
491 need_audio_processing = need_audio_processing_ ?
492 !MediaStreamAudioProcessor::IsAudioTrackProcessingEnabled() : false;
493 } 468 }
494 469
495 DCHECK(audio_processor_->InputFormat().IsValid()); 470 DCHECK(audio_processor_->InputFormat().IsValid());
496 DCHECK_EQ(audio_source->channels(), 471 DCHECK_EQ(audio_source->channels(),
497 audio_processor_->InputFormat().channels()); 472 audio_processor_->InputFormat().channels());
498 DCHECK_EQ(audio_source->frames(), 473 DCHECK_EQ(audio_source->frames(),
499 audio_processor_->InputFormat().frames_per_buffer()); 474 audio_processor_->InputFormat().frames_per_buffer());
500 475
501 // Notify the tracks on when the format changes. This will do nothing if 476 // Notify the tracks on when the format changes. This will do nothing if
502 // |tracks_to_notify_format| is empty. 477 // |tracks_to_notify_format| is empty.
(...skipping 15 matching lines...) Expand all
518 493
519 // Process and consume the data in the processor until there is not enough 494 // Process and consume the data in the processor until there is not enough
520 // data in the processor. 495 // data in the processor.
521 int16* output = NULL; 496 int16* output = NULL;
522 int new_volume = 0; 497 int new_volume = 0;
523 while (audio_processor_->ProcessAndConsumeData( 498 while (audio_processor_->ProcessAndConsumeData(
524 audio_delay, current_volume, key_pressed, &new_volume, &output)) { 499 audio_delay, current_volume, key_pressed, &new_volume, &output)) {
525 // Feed the post-processed data to the tracks. 500 // Feed the post-processed data to the tracks.
526 for (TrackList::ItemList::const_iterator it = tracks.begin(); 501 for (TrackList::ItemList::const_iterator it = tracks.begin();
527 it != tracks.end(); ++it) { 502 it != tracks.end(); ++it) {
528 (*it)->Capture(output, audio_delay, current_volume, key_pressed, 503 (*it)->Capture(output, force_report_nonzero_energy);
529 need_audio_processing, force_report_nonzero_energy);
530 } 504 }
531 505
532 if (new_volume) { 506 if (new_volume) {
533 SetVolume(new_volume); 507 SetVolume(new_volume);
534 508
535 // Update the |current_volume| to avoid passing the old volume to AGC. 509 // Update the |current_volume| to avoid passing the old volume to AGC.
536 current_volume = new_volume; 510 current_volume = new_volume;
537 } 511 }
538 } 512 }
539 } 513 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
585 hardware_buffer_size <= peer_connection_buffer_size && 559 hardware_buffer_size <= peer_connection_buffer_size &&
586 !audio_processor_->has_audio_processing()) { 560 !audio_processor_->has_audio_processing()) {
587 DVLOG(1) << "WebRtcAudioCapturer is using hardware buffer size " 561 DVLOG(1) << "WebRtcAudioCapturer is using hardware buffer size "
588 << hardware_buffer_size; 562 << hardware_buffer_size;
589 return hardware_buffer_size; 563 return hardware_buffer_size;
590 } 564 }
591 565
592 return (sample_rate / 100); 566 return (sample_rate / 100);
593 } 567 }
594 568
595 void WebRtcAudioCapturer::GetAudioProcessingParams(
596 base::TimeDelta* delay, int* volume, bool* key_pressed) {
597 base::AutoLock auto_lock(lock_);
598 *delay = audio_delay_;
599 *volume = volume_;
600 *key_pressed = key_pressed_;
601 }
602
603 void WebRtcAudioCapturer::SetCapturerSourceForTesting( 569 void WebRtcAudioCapturer::SetCapturerSourceForTesting(
604 const scoped_refptr<media::AudioCapturerSource>& source, 570 const scoped_refptr<media::AudioCapturerSource>& source,
605 media::AudioParameters params) { 571 media::AudioParameters params) {
606 // Create a new audio stream as source which uses the new source. 572 // Create a new audio stream as source which uses the new source.
607 SetCapturerSource(source, params.channel_layout(), 573 SetCapturerSource(source, params.channel_layout(),
608 static_cast<float>(params.sample_rate())); 574 static_cast<float>(params.sample_rate()));
609 } 575 }
610 576
611 } // namespace content 577 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/webrtc_audio_capturer.h ('k') | content/renderer/media/webrtc_audio_capturer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698