Index: content/renderer/media/webrtc_local_audio_renderer.cc |
diff --git a/content/renderer/media/webrtc_local_audio_renderer.cc b/content/renderer/media/webrtc_local_audio_renderer.cc |
index 1deb11e26ef96b41e27a8e935963663b09188788..ed98b283030372c315bdf3c5fb9a7df210b4985a 100644 |
--- a/content/renderer/media/webrtc_local_audio_renderer.cc |
+++ b/content/renderer/media/webrtc_local_audio_renderer.cc |
@@ -10,7 +10,9 @@ |
#include "base/metrics/histogram.h" |
#include "base/synchronization/lock.h" |
#include "content/renderer/media/audio_device_factory.h" |
+#include "content/renderer/media/media_stream_dispatcher.h" |
#include "content/renderer/media/webrtc_audio_capturer.h" |
+#include "content/renderer/render_view_impl.h" |
#include "media/audio/audio_output_device.h" |
#include "media/base/audio_bus.h" |
#include "media/base/audio_fifo.h" |
@@ -93,44 +95,6 @@ void WebRtcLocalAudioRenderer::OnSetFormat( |
capture_thread_checker_.DetachFromThread(); |
DCHECK(capture_thread_checker_.CalledOnValidThread()); |
- // Reset the |source_params_|, |sink_params_| and |loopback_fifo_| to match |
- // the new format. |
- { |
- base::AutoLock auto_lock(thread_lock_); |
- if (source_params_ == params) |
- return; |
- |
- source_params_ = params; |
- |
- sink_params_ = media::AudioParameters(source_params_.format(), |
- source_params_.channel_layout(), source_params_.channels(), |
- source_params_.input_channels(), source_params_.sample_rate(), |
- source_params_.bits_per_sample(), |
-#if defined(OS_ANDROID) |
- // On Android, input and output use the same sample rate. In order to |
- // use the low latency mode, we need to use the buffer size suggested by |
- // the AudioManager for the sink. It will later be used to decide |
- // the buffer size of the shared memory buffer. |
- frames_per_buffer_, |
-#else |
- 2 * source_params_.frames_per_buffer(), |
-#endif |
- // If DUCKING is enabled on the source, it needs to be enabled on the |
- // sink as well. |
- source_params_.effects()); |
- |
- // TODO(henrika): we could add a more dynamic solution here but I prefer |
- // a fixed size combined with bad audio at overflow. The alternative is |
- // that we start to build up latency and that can be more difficult to |
- // detect. Tests have shown that the FIFO never contains more than 2 or 3 |
- // audio frames but I have selected a max size of ten buffers just |
- // in case since these tests were performed on a 16 core, 64GB Win 7 |
- // machine. We could also add some sort of error notifier in this area if |
- // the FIFO overflows. |
- loopback_fifo_.reset(new media::AudioFifo( |
- params.channels(), 10 * params.frames_per_buffer())); |
- } |
- |
// Post a task on the main render thread to reconfigure the |sink_| with the |
// new format. |
message_loop_->PostTask( |
@@ -278,10 +242,11 @@ void WebRtcLocalAudioRenderer::MaybeStartSink() { |
if (!sink_.get() || !source_params_.IsValid()) |
return; |
- base::AutoLock auto_lock(thread_lock_); |
- |
- // Clear up the old data in the FIFO. |
- loopback_fifo_->Clear(); |
+ { |
+ // Clear up the old data in the FIFO. |
+ base::AutoLock auto_lock(thread_lock_); |
+ loopback_fifo_->Clear(); |
+ } |
if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_) |
return; |
@@ -300,6 +265,59 @@ void WebRtcLocalAudioRenderer::ReconfigureSink( |
DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()"; |
+ int implicit_ducking_effect = 0; |
+ RenderViewImpl* render_view = |
+ RenderViewImpl::FromRoutingID(source_render_view_id_); |
+ if (render_view && |
+ render_view->media_stream_dispatcher() && |
+ render_view->media_stream_dispatcher()->IsAudioDuckingActive()) { |
+ DVLOG(1) << "Forcing DUCKING to be ON for output"; |
+ implicit_ducking_effect = media::AudioParameters::DUCKING; |
+ } else { |
+ DVLOG(1) << "DUCKING not forced ON for output"; |
+ } |
+ |
+ if (source_params_ == params) |
+ return; |
+ |
+ // Reset the |source_params_|, |sink_params_| and |loopback_fifo_| to match |
+ // the new format. |
+ |
+ source_params_ = params; |
+ |
+ sink_params_ = media::AudioParameters(source_params_.format(), |
+ source_params_.channel_layout(), source_params_.channels(), |
+ source_params_.input_channels(), source_params_.sample_rate(), |
+ source_params_.bits_per_sample(), |
+#if defined(OS_ANDROID) |
+ // On Android, input and output use the same sample rate. In order to |
+ // use the low latency mode, we need to use the buffer size suggested by |
+ // the AudioManager for the sink. It will later be used to decide |
+ // the buffer size of the shared memory buffer. |
+ frames_per_buffer_, |
+#else |
+ 2 * source_params_.frames_per_buffer(), |
+#endif |
+ // If DUCKING is enabled on the source, it needs to be enabled on the |
+ // sink as well. |
+ source_params_.effects() | implicit_ducking_effect); |
+ |
+ { |
+ // TODO(henrika): we could add a more dynamic solution here but I prefer |
+ // a fixed size combined with bad audio at overflow. The alternative is |
+ // that we start to build up latency and that can be more difficult to |
+ // detect. Tests have shown that the FIFO never contains more than 2 or 3 |
+ // audio frames but I have selected a max size of ten buffers just |
+ // in case since these tests were performed on a 16 core, 64GB Win 7 |
+ // machine. We could also add some sort of error notifier in this area if |
+ // the FIFO overflows. |
+ media::AudioFifo* new_fifo = new media::AudioFifo( |
+ params.channels(), 10 * params.frames_per_buffer()); |
+ |
+ base::AutoLock auto_lock(thread_lock_); |
+ loopback_fifo_.reset(new_fifo); |
+ } |
+ |
if (!sink_) |
return; // WebRtcLocalAudioRenderer has not yet been started. |
@@ -309,6 +327,7 @@ void WebRtcLocalAudioRenderer::ReconfigureSink( |
sink_->Stop(); |
sink_started_ = false; |
} |
+ |
sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_, |
source_render_frame_id_); |
MaybeStartSink(); |