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

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

Issue 1528473003: Feed the WebRTC APM with empty far-end frames for the number of frames skipped by OS. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review. Rebase. Created 5 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/media_stream_audio_processor.h" 5 #include "content/renderer/media/media_stream_audio_processor.h"
6 6
7 #include "base/command_line.h" 7 #include "base/command_line.h"
8 #include "base/metrics/field_trial.h" 8 #include "base/metrics/field_trial.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_number_conversions.h" 10 #include "base/strings/string_number_conversions.h"
(...skipping 261 matching lines...) Expand 10 before | Expand all | Expand 10 after
272 }; 272 };
273 273
274 MediaStreamAudioProcessor::MediaStreamAudioProcessor( 274 MediaStreamAudioProcessor::MediaStreamAudioProcessor(
275 const blink::WebMediaConstraints& constraints, 275 const blink::WebMediaConstraints& constraints,
276 const MediaStreamDevice::AudioDeviceParameters& input_params, 276 const MediaStreamDevice::AudioDeviceParameters& input_params,
277 WebRtcPlayoutDataSource* playout_data_source) 277 WebRtcPlayoutDataSource* playout_data_source)
278 : render_delay_ms_(0), 278 : render_delay_ms_(0),
279 playout_data_source_(playout_data_source), 279 playout_data_source_(playout_data_source),
280 audio_mirroring_(false), 280 audio_mirroring_(false),
281 typing_detected_(false), 281 typing_detected_(false),
282 stopped_(false) { 282 stopped_(false),
283 skipped_output_frames_(0) {
283 capture_thread_checker_.DetachFromThread(); 284 capture_thread_checker_.DetachFromThread();
284 render_thread_checker_.DetachFromThread(); 285 render_thread_checker_.DetachFromThread();
285 InitializeAudioProcessingModule(constraints, input_params); 286 InitializeAudioProcessingModule(constraints, input_params);
286 287
287 aec_dump_message_filter_ = AecDumpMessageFilter::Get(); 288 aec_dump_message_filter_ = AecDumpMessageFilter::Get();
288 // In unit tests not creating a message filter, |aec_dump_message_filter_| 289 // In unit tests not creating a message filter, |aec_dump_message_filter_|
289 // will be NULL. We can just ignore that. Other unit tests and browser tests 290 // will be NULL. We can just ignore that. Other unit tests and browser tests
290 // ensure that we do get the filter when we should. 291 // ensure that we do get the filter when we should.
291 if (aec_dump_message_filter_.get()) 292 if (aec_dump_message_filter_.get())
292 aec_dump_message_filter_->AddDelegate(this); 293 aec_dump_message_filter_->AddDelegate(this);
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
425 StopEchoCancellationDump(audio_processing_.get()); 426 StopEchoCancellationDump(audio_processing_.get());
426 } 427 }
427 428
428 void MediaStreamAudioProcessor::OnIpcClosing() { 429 void MediaStreamAudioProcessor::OnIpcClosing() {
429 DCHECK(main_thread_checker_.CalledOnValidThread()); 430 DCHECK(main_thread_checker_.CalledOnValidThread());
430 aec_dump_message_filter_ = NULL; 431 aec_dump_message_filter_ = NULL;
431 } 432 }
432 433
433 void MediaStreamAudioProcessor::OnPlayoutData(media::AudioBus* audio_bus, 434 void MediaStreamAudioProcessor::OnPlayoutData(media::AudioBus* audio_bus,
434 int sample_rate, 435 int sample_rate,
435 int audio_delay_milliseconds) { 436 int audio_delay_milliseconds,
437 uint32_t skipped_frames) {
436 DCHECK(render_thread_checker_.CalledOnValidThread()); 438 DCHECK(render_thread_checker_.CalledOnValidThread());
437 DCHECK(audio_processing_->echo_control_mobile()->is_enabled() ^ 439 DCHECK(audio_processing_->echo_control_mobile()->is_enabled() ^
438 audio_processing_->echo_cancellation()->is_enabled()); 440 audio_processing_->echo_cancellation()->is_enabled());
439 441
440 TRACE_EVENT0("audio", "MediaStreamAudioProcessor::OnPlayoutData"); 442 TRACE_EVENT0("audio", "MediaStreamAudioProcessor::OnPlayoutData");
441 DCHECK_LT(audio_delay_milliseconds, 443 DCHECK_LT(audio_delay_milliseconds,
442 std::numeric_limits<base::subtle::Atomic32>::max()); 444 std::numeric_limits<base::subtle::Atomic32>::max());
443 base::subtle::Release_Store(&render_delay_ms_, audio_delay_milliseconds); 445 base::subtle::Release_Store(&render_delay_ms_, audio_delay_milliseconds);
444 446
445 InitializeRenderFifoIfNeeded(sample_rate, audio_bus->channels(), 447 InitializeRenderFifoIfNeeded(sample_rate, audio_bus->channels(),
446 audio_bus->frames()); 448 audio_bus->frames());
447 449
448 render_fifo_->Push( 450 render_fifo_->Push(
449 *audio_bus, base::TimeDelta::FromMilliseconds(audio_delay_milliseconds)); 451 *audio_bus, base::TimeDelta::FromMilliseconds(audio_delay_milliseconds));
452
453 // Feed the APM with empty frames if frames have been skipped. The APM only
454 // accepts 10 ms chunks.
455 skipped_output_frames_ += skipped_frames;
456 uint32_t frames_per_10ms = static_cast<uint32_t>(sample_rate / 100);
457 if (skipped_output_frames_ > frames_per_10ms) {
458 MediaStreamAudioBus empty_bus(audio_bus->channels(), frames_per_10ms);
459 empty_bus.bus()->Zero();
460 while (skipped_output_frames_ > frames_per_10ms) {
461 audio_processing_->AnalyzeReverseStream(
462 empty_bus.channel_ptrs(),
463 empty_bus.bus()->frames(),
464 sample_rate,
465 ChannelsToLayout(empty_bus.bus()->channels()));
466 skipped_output_frames_ -= frames_per_10ms;
467 }
468 }
469
470 // Pull data from the fifo and feed the APM.
450 MediaStreamAudioBus* analysis_bus; 471 MediaStreamAudioBus* analysis_bus;
451 base::TimeDelta audio_delay; 472 base::TimeDelta audio_delay;
452 while (render_fifo_->Consume(&analysis_bus, &audio_delay)) { 473 while (render_fifo_->Consume(&analysis_bus, &audio_delay)) {
453 // TODO(ajm): Should AnalyzeReverseStream() account for the |audio_delay|? 474 // TODO(ajm): Should AnalyzeReverseStream() account for the |audio_delay|?
454 audio_processing_->AnalyzeReverseStream( 475 audio_processing_->AnalyzeReverseStream(
455 analysis_bus->channel_ptrs(), 476 analysis_bus->channel_ptrs(),
456 analysis_bus->bus()->frames(), 477 analysis_bus->bus()->frames(),
457 sample_rate, 478 sample_rate,
458 ChannelsToLayout(audio_bus->channels())); 479 ChannelsToLayout(analysis_bus->bus()->channels()));
459 } 480 }
460 } 481 }
461 482
462 void MediaStreamAudioProcessor::OnPlayoutDataSourceChanged() { 483 void MediaStreamAudioProcessor::OnPlayoutDataSourceChanged() {
463 DCHECK(main_thread_checker_.CalledOnValidThread()); 484 DCHECK(main_thread_checker_.CalledOnValidThread());
464 // There is no need to hold a lock here since the caller guarantees that 485 // There is no need to hold a lock here since the caller guarantees that
465 // there is no more OnPlayoutData() callback on the render thread. 486 // there is no more OnPlayoutData() callback on the render thread.
466 render_thread_checker_.DetachFromThread(); 487 render_thread_checker_.DetachFromThread();
467 render_fifo_.reset(); 488 render_fifo_.reset();
468 } 489 }
(...skipping 275 matching lines...) Expand 10 before | Expand all | Expand 10 after
744 if (echo_information_) { 765 if (echo_information_) {
745 echo_information_.get()->UpdateAecDelayStats(ap->echo_cancellation()); 766 echo_information_.get()->UpdateAecDelayStats(ap->echo_cancellation());
746 } 767 }
747 768
748 // Return 0 if the volume hasn't been changed, and otherwise the new volume. 769 // Return 0 if the volume hasn't been changed, and otherwise the new volume.
749 return (agc->stream_analog_level() == volume) ? 770 return (agc->stream_analog_level() == volume) ?
750 0 : agc->stream_analog_level(); 771 0 : agc->stream_analog_level();
751 } 772 }
752 773
753 } // namespace content 774 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/media_stream_audio_processor.h ('k') | content/renderer/media/media_stream_audio_processor_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698