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

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

Issue 1666363005: Switching audio clients to using RestartableAudioRendererSink interface as a sink. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: export fix Created 4 years, 10 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 <utility> 7 #include <utility>
8 8
9 #include "base/location.h" 9 #include "base/location.h"
10 #include "base/logging.h" 10 #include "base/logging.h"
11 #include "base/metrics/histogram.h" 11 #include "base/metrics/histogram.h"
12 #include "base/synchronization/lock.h" 12 #include "base/synchronization/lock.h"
13 #include "base/thread_task_runner_handle.h" 13 #include "base/thread_task_runner_handle.h"
14 #include "base/trace_event/trace_event.h" 14 #include "base/trace_event/trace_event.h"
15 #include "content/renderer/media/audio_device_factory.h" 15 #include "content/renderer/media/audio_device_factory.h"
16 #include "content/renderer/media/media_stream_dispatcher.h" 16 #include "content/renderer/media/media_stream_dispatcher.h"
17 #include "content/renderer/media/webrtc_audio_capturer.h" 17 #include "content/renderer/media/webrtc_audio_capturer.h"
18 #include "content/renderer/media/webrtc_audio_renderer.h" 18 #include "content/renderer/media/webrtc_audio_renderer.h"
19 #include "content/renderer/render_frame_impl.h" 19 #include "content/renderer/render_frame_impl.h"
20 #include "media/audio/audio_output_device.h"
21 #include "media/base/audio_bus.h" 20 #include "media/base/audio_bus.h"
22 #include "media/base/audio_shifter.h" 21 #include "media/base/audio_shifter.h"
23 22
24 namespace content { 23 namespace content {
25 24
26 namespace { 25 namespace {
27 26
28 enum LocalRendererSinkStates { 27 enum LocalRendererSinkStates {
29 kSinkStarted = 0, 28 kSinkStarted = 0,
30 kSinkNeverStarted, 29 kSinkNeverStarted,
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after
119 } 118 }
120 119
121 void WebRtcLocalAudioRenderer::Start() { 120 void WebRtcLocalAudioRenderer::Start() {
122 DVLOG(1) << "WebRtcLocalAudioRenderer::Start()"; 121 DVLOG(1) << "WebRtcLocalAudioRenderer::Start()";
123 DCHECK(task_runner_->BelongsToCurrentThread()); 122 DCHECK(task_runner_->BelongsToCurrentThread());
124 123
125 // We get audio data from |audio_track_|... 124 // We get audio data from |audio_track_|...
126 MediaStreamAudioSink::AddToAudioTrack(this, audio_track_); 125 MediaStreamAudioSink::AddToAudioTrack(this, audio_track_);
127 // ...and |sink_| will get audio data from us. 126 // ...and |sink_| will get audio data from us.
128 DCHECK(!sink_.get()); 127 DCHECK(!sink_.get());
129 sink_ = 128 sink_ = AudioDeviceFactory::NewOutputDevice(
130 AudioDeviceFactory::NewOutputDevice(source_render_frame_id_, session_id_, 129 AudioDeviceFactory::kSourceLocalUserMedia, source_render_frame_id_,
131 output_device_id_, security_origin_); 130 session_id_, output_device_id_, security_origin_);
132 131
133 base::AutoLock auto_lock(thread_lock_); 132 base::AutoLock auto_lock(thread_lock_);
134 last_render_time_ = base::TimeTicks::Now(); 133 last_render_time_ = base::TimeTicks::Now();
135 playing_ = false; 134 playing_ = false;
136 } 135 }
137 136
138 void WebRtcLocalAudioRenderer::Stop() { 137 void WebRtcLocalAudioRenderer::Stop() {
139 DVLOG(1) << "WebRtcLocalAudioRenderer::Stop()"; 138 DVLOG(1) << "WebRtcLocalAudioRenderer::Stop()";
140 DCHECK(task_runner_->BelongsToCurrentThread()); 139 DCHECK(task_runner_->BelongsToCurrentThread());
141 140
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 return true; 230 return true;
232 } 231 }
233 232
234 void WebRtcLocalAudioRenderer::SwitchOutputDevice( 233 void WebRtcLocalAudioRenderer::SwitchOutputDevice(
235 const std::string& device_id, 234 const std::string& device_id,
236 const url::Origin& security_origin, 235 const url::Origin& security_origin,
237 const media::SwitchOutputDeviceCB& callback) { 236 const media::SwitchOutputDeviceCB& callback) {
238 DVLOG(1) << "WebRtcLocalAudioRenderer::SwitchOutputDevice()"; 237 DVLOG(1) << "WebRtcLocalAudioRenderer::SwitchOutputDevice()";
239 DCHECK(task_runner_->BelongsToCurrentThread()); 238 DCHECK(task_runner_->BelongsToCurrentThread());
240 239
241 scoped_refptr<media::AudioOutputDevice> new_sink = 240 scoped_refptr<media::AudioRendererSink> new_sink =
242 AudioDeviceFactory::NewOutputDevice(source_render_frame_id_, session_id_, 241 AudioDeviceFactory::NewOutputDevice(
243 device_id, security_origin); 242 AudioDeviceFactory::kSourceLocalUserMedia, source_render_frame_id_,
244 if (new_sink->GetDeviceStatus() != media::OUTPUT_DEVICE_STATUS_OK) { 243 session_id_, device_id, security_origin);
245 callback.Run(new_sink->GetDeviceStatus()); 244 media::OutputDeviceStatus new_sink_status =
245 new_sink->GetOutputDevice()->GetDeviceStatus();
246 if (new_sink_status != media::OUTPUT_DEVICE_STATUS_OK) {
247 callback.Run(new_sink_status);
246 return; 248 return;
247 } 249 }
248 250
249 output_device_id_ = device_id; 251 output_device_id_ = device_id;
250 security_origin_ = security_origin; 252 security_origin_ = security_origin;
251 bool was_sink_started = sink_started_; 253 bool was_sink_started = sink_started_;
252 254
253 if (sink_.get()) 255 if (sink_.get())
254 sink_->Stop(); 256 sink_->Stop();
255 257
256 sink_started_ = false; 258 sink_started_ = false;
257 sink_ = new_sink; 259 sink_ = new_sink;
258 int frames_per_buffer = sink_->GetOutputParameters().frames_per_buffer(); 260 int frames_per_buffer =
261 sink_->GetOutputDevice()->GetOutputParameters().frames_per_buffer();
259 sink_params_ = source_params_; 262 sink_params_ = source_params_;
260 sink_params_.set_frames_per_buffer(WebRtcAudioRenderer::GetOptimalBufferSize( 263 sink_params_.set_frames_per_buffer(WebRtcAudioRenderer::GetOptimalBufferSize(
261 source_params_.sample_rate(), frames_per_buffer)); 264 source_params_.sample_rate(), frames_per_buffer));
262 265
263 if (was_sink_started) 266 if (was_sink_started)
264 MaybeStartSink(); 267 MaybeStartSink();
265 268
266 callback.Run(media::OUTPUT_DEVICE_STATUS_OK); 269 callback.Run(media::OUTPUT_DEVICE_STATUS_OK);
267 } 270 }
268 271
269 media::AudioParameters WebRtcLocalAudioRenderer::GetOutputParameters() { 272 media::AudioParameters WebRtcLocalAudioRenderer::GetOutputParameters() {
270 DCHECK(task_runner_->BelongsToCurrentThread()); 273 DCHECK(task_runner_->BelongsToCurrentThread());
271 if (!sink_.get()) 274 if (!sink_.get())
272 return media::AudioParameters(); 275 return media::AudioParameters();
273 276
274 return sink_->GetOutputParameters(); 277 return sink_->GetOutputDevice()->GetOutputParameters();
275 } 278 }
276 279
277 media::OutputDeviceStatus WebRtcLocalAudioRenderer::GetDeviceStatus() { 280 media::OutputDeviceStatus WebRtcLocalAudioRenderer::GetDeviceStatus() {
278 DCHECK(task_runner_->BelongsToCurrentThread()); 281 DCHECK(task_runner_->BelongsToCurrentThread());
279 if (!sink_.get()) 282 if (!sink_.get())
280 return media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL; 283 return media::OUTPUT_DEVICE_STATUS_ERROR_INTERNAL;
281 284
282 return sink_->GetDeviceStatus(); 285 return sink_->GetOutputDevice()->GetDeviceStatus();
283 } 286 }
284 287
285 void WebRtcLocalAudioRenderer::MaybeStartSink() { 288 void WebRtcLocalAudioRenderer::MaybeStartSink() {
286 DCHECK(task_runner_->BelongsToCurrentThread()); 289 DCHECK(task_runner_->BelongsToCurrentThread());
287 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink()"; 290 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink()";
288 291
289 if (!sink_.get() || !source_params_.IsValid()) 292 if (!sink_.get() || !source_params_.IsValid())
290 return; 293 return;
291 294
292 { 295 {
293 // Clear up the old data in the FIFO. 296 // Clear up the old data in the FIFO.
294 base::AutoLock auto_lock(thread_lock_); 297 base::AutoLock auto_lock(thread_lock_);
295 audio_shifter_->Flush(); 298 audio_shifter_->Flush();
296 } 299 }
297 300
298 if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_ || 301 if (!sink_params_.IsValid() || !playing_ || !volume_ || sink_started_ ||
299 sink_->GetDeviceStatus() != media::OUTPUT_DEVICE_STATUS_OK) 302 sink_->GetOutputDevice()->GetDeviceStatus() !=
303 media::OUTPUT_DEVICE_STATUS_OK)
300 return; 304 return;
301 305
302 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_."; 306 DVLOG(1) << "WebRtcLocalAudioRenderer::MaybeStartSink() -- Starting sink_.";
303 sink_->Initialize(sink_params_, this); 307 sink_->Initialize(sink_params_, this);
304 sink_->Start(); 308 sink_->Start();
309 sink_->Play(); // Not all the sinks play on start.
305 sink_started_ = true; 310 sink_started_ = true;
306 UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates", 311 UMA_HISTOGRAM_ENUMERATION("Media.LocalRendererSinkStates",
307 kSinkStarted, kSinkStatesMax); 312 kSinkStarted, kSinkStatesMax);
308 } 313 }
309 314
310 void WebRtcLocalAudioRenderer::ReconfigureSink( 315 void WebRtcLocalAudioRenderer::ReconfigureSink(
311 const media::AudioParameters& params) { 316 const media::AudioParameters& params) {
312 DCHECK(task_runner_->BelongsToCurrentThread()); 317 DCHECK(task_runner_->BelongsToCurrentThread());
313 318
314 DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()"; 319 DVLOG(1) << "WebRtcLocalAudioRenderer::ReconfigureSink()";
(...skipping 21 matching lines...) Expand all
336 audio_shifter_.reset(new_shifter); 341 audio_shifter_.reset(new_shifter);
337 } 342 }
338 343
339 if (!sink_.get()) 344 if (!sink_.get())
340 return; // WebRtcLocalAudioRenderer has not yet been started. 345 return; // WebRtcLocalAudioRenderer has not yet been started.
341 346
342 // Stop |sink_| and re-create a new one to be initialized with different audio 347 // Stop |sink_| and re-create a new one to be initialized with different audio
343 // parameters. Then, invoke MaybeStartSink() to restart everything again. 348 // parameters. Then, invoke MaybeStartSink() to restart everything again.
344 sink_->Stop(); 349 sink_->Stop();
345 sink_started_ = false; 350 sink_started_ = false;
346 sink_ = 351 sink_ = AudioDeviceFactory::NewOutputDevice(
347 AudioDeviceFactory::NewOutputDevice(source_render_frame_id_, session_id_, 352 AudioDeviceFactory::kSourceLocalUserMedia, source_render_frame_id_,
348 output_device_id_, security_origin_); 353 session_id_, output_device_id_, security_origin_);
349 int frames_per_buffer = sink_->GetOutputParameters().frames_per_buffer(); 354 int frames_per_buffer =
355 sink_->GetOutputDevice()->GetOutputParameters().frames_per_buffer();
350 sink_params_ = source_params_; 356 sink_params_ = source_params_;
351 sink_params_.set_frames_per_buffer(WebRtcAudioRenderer::GetOptimalBufferSize( 357 sink_params_.set_frames_per_buffer(WebRtcAudioRenderer::GetOptimalBufferSize(
352 source_params_.sample_rate(), frames_per_buffer)); 358 source_params_.sample_rate(), frames_per_buffer));
353 MaybeStartSink(); 359 MaybeStartSink();
354 } 360 }
355 361
356 } // namespace content 362 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698