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

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

Issue 396263004: Switch the input code to use AudioBlockFifo (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: 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 | Annotate | Revision Log
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/media_stream_dispatcher.h"
14 #include "content/renderer/media/webrtc_audio_capturer.h" 14 #include "content/renderer/media/webrtc_audio_capturer.h"
15 #include "content/renderer/render_frame_impl.h" 15 #include "content/renderer/render_frame_impl.h"
16 #include "media/audio/audio_output_device.h" 16 #include "media/audio/audio_output_device.h"
17 #include "media/base/audio_block_fifo.h"
17 #include "media/base/audio_bus.h" 18 #include "media/base/audio_bus.h"
18 #include "media/base/audio_fifo.h"
19 19
20 namespace content { 20 namespace content {
21 21
22 namespace { 22 namespace {
23 23
24 enum LocalRendererSinkStates { 24 enum LocalRendererSinkStates {
25 kSinkStarted = 0, 25 kSinkStarted = 0,
26 kSinkNeverStarted, 26 kSinkNeverStarted,
27 kSinkStatesMax // Must always be last! 27 kSinkStatesMax // Must always be last!
28 }; 28 };
29 29
30 } // namespace 30 } // namespace
31 31
32 // media::AudioRendererSink::RenderCallback implementation 32 // media::AudioRendererSink::RenderCallback implementation
33 int WebRtcLocalAudioRenderer::Render( 33 int WebRtcLocalAudioRenderer::Render(
34 media::AudioBus* audio_bus, int audio_delay_milliseconds) { 34 media::AudioBus* audio_bus, int audio_delay_milliseconds) {
35 TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::Render"); 35 TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::Render");
36 base::AutoLock auto_lock(thread_lock_); 36 base::AutoLock auto_lock(thread_lock_);
37 37
38 if (!playing_ || !volume_ || !loopback_fifo_) { 38 if (!playing_ || !volume_ || !loopback_fifo_) {
39 audio_bus->Zero(); 39 audio_bus->Zero();
40 return 0; 40 return 0;
41 } 41 }
42 42
43 // Provide data by reading from the FIFO if the FIFO contains enough 43 // Provide data by reading from the FIFO if the FIFO contains enough
44 // to fulfill the request. 44 // to fulfill the request.
45 if (loopback_fifo_->frames() >= audio_bus->frames()) { 45 if (loopback_fifo_->available_blocks()) {
46 loopback_fifo_->Consume(audio_bus, 0, audio_bus->frames()); 46 const media::AudioBus* audio_data = loopback_fifo_->Consume();
47 DCHECK_EQ(audio_data->frames(), audio_bus->frames());
48 audio_data->CopyTo(audio_bus);
47 } else { 49 } else {
48 audio_bus->Zero(); 50 audio_bus->Zero();
49 // This warning is perfectly safe if it happens for the first audio 51 // This warning is perfectly safe if it happens for the first audio
50 // frames. It should not happen in a steady-state mode. 52 // frames. It should not happen in a steady-state mode.
51 DVLOG(2) << "loopback FIFO is empty"; 53 DVLOG(2) << "loopback FIFO is empty";
52 } 54 }
53 55
54 return audio_bus->frames(); 56 return audio_bus->frames();
55 } 57 }
56 58
57 void WebRtcLocalAudioRenderer::OnRenderError() { 59 void WebRtcLocalAudioRenderer::OnRenderError() {
58 NOTIMPLEMENTED(); 60 NOTIMPLEMENTED();
59 } 61 }
60 62
61 // content::MediaStreamAudioSink implementation 63 // content::MediaStreamAudioSink implementation
62 void WebRtcLocalAudioRenderer::OnData(const int16* audio_data, 64 void WebRtcLocalAudioRenderer::OnData(const int16* audio_data,
63 int sample_rate, 65 int sample_rate,
64 int number_of_channels, 66 int number_of_channels,
65 int number_of_frames) { 67 int number_of_frames) {
66 DCHECK(capture_thread_checker_.CalledOnValidThread()); 68 DCHECK(capture_thread_checker_.CalledOnValidThread());
67 TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::CaptureData"); 69 TRACE_EVENT0("audio", "WebRtcLocalAudioRenderer::CaptureData");
68 base::AutoLock auto_lock(thread_lock_); 70 base::AutoLock auto_lock(thread_lock_);
69 if (!playing_ || !volume_ || !loopback_fifo_) 71 if (!playing_ || !volume_ || !loopback_fifo_)
70 return; 72 return;
71 73
72 // Push captured audio to FIFO so it can be read by a local sink. 74 // Push captured audio to FIFO so it can be read by a local sink.
73 if (loopback_fifo_->frames() + number_of_frames <= 75 if (loopback_fifo_->GetUnfilledFrames() >= number_of_frames) {
74 loopback_fifo_->max_frames()) { 76 loopback_fifo_->Push(audio_data, number_of_frames, sizeof(audio_data[0]));
75 scoped_ptr<media::AudioBus> audio_source = media::AudioBus::Create(
76 number_of_channels, number_of_frames);
77 audio_source->FromInterleaved(audio_data,
78 audio_source->frames(),
79 sizeof(audio_data[0]));
80 loopback_fifo_->Push(audio_source.get());
81 77
82 const base::TimeTicks now = base::TimeTicks::Now(); 78 const base::TimeTicks now = base::TimeTicks::Now();
83 total_render_time_ += now - last_render_time_; 79 total_render_time_ += now - last_render_time_;
84 last_render_time_ = now; 80 last_render_time_ = now;
85 } else { 81 } else {
86 DVLOG(1) << "FIFO is full"; 82 DVLOG(1) << "FIFO is full";
87 } 83 }
88 } 84 }
89 85
90 void WebRtcLocalAudioRenderer::OnSetFormat( 86 void WebRtcLocalAudioRenderer::OnSetFormat(
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
304 300
305 { 301 {
306 // TODO(henrika): we could add a more dynamic solution here but I prefer 302 // 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 303 // 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 304 // 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 305 // 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 306 // 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 307 // 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 308 // machine. We could also add some sort of error notifier in this area if
313 // the FIFO overflows. 309 // the FIFO overflows.
314 media::AudioFifo* new_fifo = new media::AudioFifo( 310 const int blocks_of_buffers =
315 params.channels(), 10 * params.frames_per_buffer()); 311 10 * params.frames_per_buffer() / sink_params_.frames_per_buffer() + 1;
312 media::AudioBlockFifo* new_fifo = new media::AudioBlockFifo(
313 params.channels(), sink_params_.frames_per_buffer(), blocks_of_buffers);
316 314
317 base::AutoLock auto_lock(thread_lock_); 315 base::AutoLock auto_lock(thread_lock_);
318 loopback_fifo_.reset(new_fifo); 316 loopback_fifo_.reset(new_fifo);
319 } 317 }
320 318
321 if (!sink_) 319 if (!sink_)
322 return; // WebRtcLocalAudioRenderer has not yet been started. 320 return; // WebRtcLocalAudioRenderer has not yet been started.
323 321
324 // Stop |sink_| and re-create a new one to be initialized with different audio 322 // Stop |sink_| and re-create a new one to be initialized with different audio
325 // parameters. Then, invoke MaybeStartSink() to restart everything again. 323 // parameters. Then, invoke MaybeStartSink() to restart everything again.
326 if (sink_started_) { 324 if (sink_started_) {
327 sink_->Stop(); 325 sink_->Stop();
328 sink_started_ = false; 326 sink_started_ = false;
329 } 327 }
330 328
331 sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_, 329 sink_ = AudioDeviceFactory::NewOutputDevice(source_render_view_id_,
332 source_render_frame_id_); 330 source_render_frame_id_);
333 MaybeStartSink(); 331 MaybeStartSink();
334 } 332 }
335 333
336 } // namespace content 334 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698