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

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

Issue 367923004: Turn audio ducking on by default on Windows again. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase, update tests, logging and documentation Created 6 years, 5 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_local_audio_renderer.h" 5 #include "content/renderer/media/webrtc_local_audio_renderer.h"
6 6
7 #include "base/debug/trace_event.h" 7 #include "base/debug/trace_event.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/message_loop/message_loop_proxy.h" 9 #include "base/message_loop/message_loop_proxy.h"
10 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
11 #include "base/synchronization/lock.h" 11 #include "base/synchronization/lock.h"
12 #include "content/renderer/media/audio_device_factory.h" 12 #include "content/renderer/media/audio_device_factory.h"
13 #include "content/renderer/media/media_stream_dispatcher.h"
13 #include "content/renderer/media/webrtc_audio_capturer.h" 14 #include "content/renderer/media/webrtc_audio_capturer.h"
15 #include "content/renderer/render_view_impl.h"
14 #include "media/audio/audio_output_device.h" 16 #include "media/audio/audio_output_device.h"
15 #include "media/base/audio_bus.h" 17 #include "media/base/audio_bus.h"
16 #include "media/base/audio_fifo.h" 18 #include "media/base/audio_fifo.h"
17 19
18 namespace content { 20 namespace content {
19 21
20 namespace { 22 namespace {
21 23
22 enum LocalRendererSinkStates { 24 enum LocalRendererSinkStates {
23 kSinkStarted = 0, 25 kSinkStarted = 0,
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
86 } 88 }
87 89
88 void WebRtcLocalAudioRenderer::OnSetFormat( 90 void WebRtcLocalAudioRenderer::OnSetFormat(
89 const media::AudioParameters& params) { 91 const media::AudioParameters& params) {
90 DVLOG(1) << "WebRtcLocalAudioRenderer::OnSetFormat()"; 92 DVLOG(1) << "WebRtcLocalAudioRenderer::OnSetFormat()";
91 // If the source is restarted, we might have changed to another capture 93 // If the source is restarted, we might have changed to another capture
92 // thread. 94 // thread.
93 capture_thread_checker_.DetachFromThread(); 95 capture_thread_checker_.DetachFromThread();
94 DCHECK(capture_thread_checker_.CalledOnValidThread()); 96 DCHECK(capture_thread_checker_.CalledOnValidThread());
95 97
96 // Reset the |source_params_|, |sink_params_| and |loopback_fifo_| to match
97 // the new format.
98 {
99 base::AutoLock auto_lock(thread_lock_);
100 if (source_params_ == params)
101 return;
102
103 source_params_ = params;
104
105 sink_params_ = media::AudioParameters(source_params_.format(),
106 source_params_.channel_layout(), source_params_.channels(),
107 source_params_.input_channels(), source_params_.sample_rate(),
108 source_params_.bits_per_sample(),
109 #if defined(OS_ANDROID)
110 // On Android, input and output use the same sample rate. In order to
111 // use the low latency mode, we need to use the buffer size suggested by
112 // the AudioManager for the sink. It will later be used to decide
113 // the buffer size of the shared memory buffer.
114 frames_per_buffer_,
115 #else
116 2 * source_params_.frames_per_buffer(),
117 #endif
118 // If DUCKING is enabled on the source, it needs to be enabled on the
119 // sink as well.
120 source_params_.effects());
121
122 // TODO(henrika): we could add a more dynamic solution here but I prefer
123 // a fixed size combined with bad audio at overflow. The alternative is
124 // that we start to build up latency and that can be more difficult to
125 // detect. Tests have shown that the FIFO never contains more than 2 or 3
126 // audio frames but I have selected a max size of ten buffers just
127 // in case since these tests were performed on a 16 core, 64GB Win 7
128 // machine. We could also add some sort of error notifier in this area if
129 // the FIFO overflows.
130 loopback_fifo_.reset(new media::AudioFifo(
131 params.channels(), 10 * params.frames_per_buffer()));
132 }
133
134 // Post a task on the main render thread to reconfigure the |sink_| with the 98 // Post a task on the main render thread to reconfigure the |sink_| with the
135 // new format. 99 // new format.
136 message_loop_->PostTask( 100 message_loop_->PostTask(
137 FROM_HERE, 101 FROM_HERE,
138 base::Bind(&WebRtcLocalAudioRenderer::ReconfigureSink, this, 102 base::Bind(&WebRtcLocalAudioRenderer::ReconfigureSink, this,
139 params)); 103 params));
140 } 104 }
141 105
142 // WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer implementation. 106 // WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer implementation.
143 WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer( 107 WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer(
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 } 232 }
269 233
270 bool WebRtcLocalAudioRenderer::IsLocalRenderer() const { 234 bool WebRtcLocalAudioRenderer::IsLocalRenderer() const {
271 return true; 235 return true;
272 } 236 }
273 237
274 void WebRtcLocalAudioRenderer::MaybeStartSink() { 238 void WebRtcLocalAudioRenderer::MaybeStartSink() {
275 DCHECK(message_loop_->BelongsToCurrentThread()); 239 DCHECK(message_loop_->BelongsToCurrentThread());
276 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink()"; 240 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink()";
277 241
278 if (!sink_.get() || !source_params_.IsValid()) 242 if (!sink_.get())
279 return; 243 return;
280 244
281 base::AutoLock auto_lock(thread_lock_); 245 base::AutoLock auto_lock(thread_lock_);
282 246
247 if (!source_params_.IsValid())
248 return;
249
283 // Clear up the old data in the FIFO. 250 // Clear up the old data in the FIFO.
284 loopback_fifo_->Clear(); 251 loopback_fifo_->Clear();
285 252
286 if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_) 253 if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_)
287 return; 254 return;
288 255
289 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_."; 256 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_.";
290 sink_->InitializeWithSessionId(sink_params_, this, session_id_); 257 sink_->InitializeWithSessionId(sink_params_, this, session_id_);
291 sink_->Start(); 258 sink_->Start();
292 sink_started_ = true; 259 sink_started_ = true;
293 UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates", 260 UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates",
294 kSinkStarted, kSinkStatesMax); 261 kSinkStarted, kSinkStatesMax);
295 } 262 }
296 263
297 void WebRtcLocalAudioRenderer::ReconfigureSink( 264 void WebRtcLocalAudioRenderer::ReconfigureSink(
298 const media::AudioParameters& params) { 265 const media::AudioParameters& params) {
299 DCHECK(message_loop_->BelongsToCurrentThread()); 266 DCHECK(message_loop_->BelongsToCurrentThread());
300 267
301 DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()"; 268 DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()";
302 269
270 int implicit_ducking_effect = 0;
271 RenderViewImpl* render_view =
272 RenderViewImpl::FromRoutingID(source_render_view_id_);
273 if (render_view &&
274 render_view->media_stream_dispatcher() &&
275 render_view->media_stream_dispatcher()->IsAudioDuckingActive()) {
276 DVLOG(1) << "Forcing DUCKING to be ON for output";
277 implicit_ducking_effect = media::AudioParameters::DUCKING;
278 } else {
279 DVLOG(1) << "DUCKING not forced ON for output";
280 }
281
282 // Reset the |source_params_|, |sink_params_| and |loopback_fifo_| to match
283 // the new format.
284 {
285 base::AutoLock auto_lock(thread_lock_);
no longer working on chromium 2014/07/08 10:42:35 with your move, I believe |source_params_| and |si
tommi (sloooow) - chröme 2014/07/08 12:30:56 Great. thanks for pointing that out.
286 if (source_params_ == params)
287 return;
288
289 source_params_ = params;
290
291 sink_params_ = media::AudioParameters(source_params_.format(),
292 source_params_.channel_layout(), source_params_.channels(),
293 source_params_.input_channels(), source_params_.sample_rate(),
294 source_params_.bits_per_sample(),
295 #if defined(OS_ANDROID)
296 // On Android, input and output use the same sample rate. In order to
297 // use the low latency mode, we need to use the buffer size suggested by
298 // the AudioManager for the sink. It will later be used to decide
299 // the buffer size of the shared memory buffer.
300 frames_per_buffer_,
301 #else
302 2 * source_params_.frames_per_buffer(),
303 #endif
304 // If DUCKING is enabled on the source, it needs to be enabled on the
305 // sink as well.
306 source_params_.effects() | implicit_ducking_effect);
307
308 // TODO(henrika): we could add a more dynamic solution here but I prefer
309 // a fixed size combined with bad audio at overflow. The alternative is
310 // that we start to build up latency and that can be more difficult to
311 // detect. Tests have shown that the FIFO never contains more than 2 or 3
312 // audio frames but I have selected a max size of ten buffers just
313 // in case since these tests were performed on a 16 core, 64GB Win 7
314 // machine. We could also add some sort of error notifier in this area if
315 // the FIFO overflows.
316 loopback_fifo_.reset(new media::AudioFifo(
317 params.channels(), 10 * params.frames_per_buffer()));
318 }
319
303 if (!sink_) 320 if (!sink_)
304 return; // WebRtcLocalAudioRenderer has not yet been started. 321 return; // WebRtcLocalAudioRenderer has not yet been started.
305 322
306 // Stop |sink_| and re-create a new one to be initialized with different audio 323 // Stop |sink_| and re-create a new one to be initialized with different audio
307 // parameters. Then, invoke MaybeStartSink() to restart everything again. 324 // parameters. Then, invoke MaybeStartSink() to restart everything again.
308 if (sink_started_) { 325 if (sink_started_) {
309 sink_->Stop(); 326 sink_->Stop();
310 sink_started_ = false; 327 sink_started_ = false;
311 } 328 }
312 sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_, 329 sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_,
313 source_render_frame_id_); 330 source_render_frame_id_);
314 MaybeStartSink(); 331 MaybeStartSink();
315 } 332 }
316 333
317 } // namespace content 334 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698