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

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: Address comments 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 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
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() || !source_params_.IsValid())
279 return; 243 return;
280 244
281 base::AutoLock auto_lock(thread_lock_); 245 {
282 246 // Clear up the old data in the FIFO.
283 // Clear up the old data in the FIFO. 247 base::AutoLock auto_lock(thread_lock_);
284 loopback_fifo_->Clear(); 248 loopback_fifo_->Clear();
249 }
285 250
286 if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_) 251 if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_)
287 return; 252 return;
288 253
289 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_."; 254 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_.";
290 sink_->InitializeWithSessionId(sink_params_, this, session_id_); 255 sink_->InitializeWithSessionId(sink_params_, this, session_id_);
291 sink_->Start(); 256 sink_->Start();
292 sink_started_ = true; 257 sink_started_ = true;
293 UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates", 258 UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates",
294 kSinkStarted, kSinkStatesMax); 259 kSinkStarted, kSinkStatesMax);
295 } 260 }
296 261
297 void WebRtcLocalAudioRenderer::ReconfigureSink( 262 void WebRtcLocalAudioRenderer::ReconfigureSink(
298 const media::AudioParameters& params) { 263 const media::AudioParameters& params) {
299 DCHECK(message_loop_->BelongsToCurrentThread()); 264 DCHECK(message_loop_->BelongsToCurrentThread());
300 265
301 DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()"; 266 DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()";
302 267
268 int implicit_ducking_effect = 0;
269 RenderViewImpl* render_view =
270 RenderViewImpl::FromRoutingID(source_render_view_id_);
271 if (render_view &&
272 render_view->media_stream_dispatcher() &&
273 render_view->media_stream_dispatcher()->IsAudioDuckingActive()) {
274 DVLOG(1) << "Forcing DUCKING to be ON for output";
275 implicit_ducking_effect = media::AudioParameters::DUCKING;
276 } else {
277 DVLOG(1) << "DUCKING not forced ON for output";
278 }
279
280 if (source_params_ == params)
281 return;
282
283 // Reset the |source_params_|, |sink_params_| and |loopback_fifo_| to match
284 // the new format.
285
286 source_params_ = params;
287
288 sink_params_ = media::AudioParameters(source_params_.format(),
289 source_params_.channel_layout(), source_params_.channels(),
290 source_params_.input_channels(), source_params_.sample_rate(),
291 source_params_.bits_per_sample(),
292 #if defined(OS_ANDROID)
293 // On Android, input and output use the same sample rate. In order to
294 // use the low latency mode, we need to use the buffer size suggested by
295 // the AudioManager for the sink. It will later be used to decide
296 // the buffer size of the shared memory buffer.
297 frames_per_buffer_,
298 #else
299 2 * source_params_.frames_per_buffer(),
300 #endif
301 // If DUCKING is enabled on the source, it needs to be enabled on the
302 // sink as well.
303 source_params_.effects() | implicit_ducking_effect);
304
305 {
306 // TODO(henrika): we could add a more dynamic solution here but I prefer
307 // a fixed size combined with bad audio at overflow. The alternative is
308 // that we start to build up latency and that can be more difficult to
309 // detect. Tests have shown that the FIFO never contains more than 2 or 3
310 // audio frames but I have selected a max size of ten buffers just
311 // in case since these tests were performed on a 16 core, 64GB Win 7
312 // machine. We could also add some sort of error notifier in this area if
313 // the FIFO overflows.
314 media::AudioFifo* new_fifo = new media::AudioFifo(
315 params.channels(), 10 * params.frames_per_buffer());
316
317 base::AutoLock auto_lock(thread_lock_);
318 loopback_fifo_.reset(new_fifo);
319 }
320
303 if (!sink_) 321 if (!sink_)
304 return; // WebRtcLocalAudioRenderer has not yet been started. 322 return; // WebRtcLocalAudioRenderer has not yet been started.
305 323
306 // Stop |sink_| and re-create a new one to be initialized with different audio 324 // Stop |sink_| and re-create a new one to be initialized with different audio
307 // parameters. Then, invoke MaybeStartSink() to restart everything again. 325 // parameters. Then, invoke MaybeStartSink() to restart everything again.
308 if (sink_started_) { 326 if (sink_started_) {
309 sink_->Stop(); 327 sink_->Stop();
310 sink_started_ = false; 328 sink_started_ = false;
311 } 329 }
330
312 sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_, 331 sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_,
313 source_render_frame_id_); 332 source_render_frame_id_);
314 MaybeStartSink(); 333 MaybeStartSink();
315 } 334 }
316 335
317 } // namespace content 336 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698