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

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

Issue 37793005: move the APM to chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: added a switch, it uses the APM in WebRtc if the switch is off, otherwise use the APM in Chrome. Created 7 years, 1 month 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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_source_provider.h" 5 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "content/renderer/render_thread_impl.h" 8 #include "content/renderer/render_thread_impl.h"
9 #include "media/audio/audio_parameters.h" 9 #include "media/audio/audio_parameters.h"
10 #include "media/base/audio_fifo.h" 10 #include "media/base/audio_fifo.h"
11 #include "media/base/audio_hardware_config.h" 11 #include "media/base/audio_hardware_config.h"
12 #include "third_party/WebKit/public/web/WebAudioSourceProviderClient.h" 12 #include "third_party/WebKit/public/web/WebAudioSourceProviderClient.h"
13 13
14 using WebKit::WebVector; 14 using WebKit::WebVector;
15 15
16 namespace content { 16 namespace content {
17 17
18 static const size_t kMaxNumberOfBuffers = 10; 18 static const size_t kMaxNumberOfBuffers = 10;
19 19
20 // Size of the buffer that WebAudio processes each time, it is the same value 20 // Size of the buffer that WebAudio processes each time, it is the same value
21 // as AudioNode::ProcessingSizeInFrames in WebKit. 21 // as AudioNode::ProcessingSizeInFrames in WebKit.
22 // static 22 // static
23 const size_t WebRtcLocalAudioSourceProvider::kWebAudioRenderBufferSize = 128; 23 const size_t WebRtcLocalAudioSourceProvider::kWebAudioRenderBufferSize = 128;
24 24
25 WebRtcLocalAudioSourceProvider::WebRtcLocalAudioSourceProvider() 25 WebRtcLocalAudioSourceProvider::WebRtcLocalAudioSourceProvider()
26 : audio_delay_ms_(0), 26 : is_enabled_(false) {
27 volume_(1),
28 key_pressed_(false),
29 is_enabled_(false) {
30 } 27 }
31 28
32 WebRtcLocalAudioSourceProvider::~WebRtcLocalAudioSourceProvider() { 29 WebRtcLocalAudioSourceProvider::~WebRtcLocalAudioSourceProvider() {
33 if (audio_converter_.get()) 30 if (audio_converter_.get())
34 audio_converter_->RemoveInput(this); 31 audio_converter_->RemoveInput(this);
35 } 32 }
36 33
37 void WebRtcLocalAudioSourceProvider::Initialize( 34 void WebRtcLocalAudioSourceProvider::SetCaptureFormat(
38 const media::AudioParameters& source_params) { 35 const media::AudioParameters& params) {
39 DCHECK(thread_checker_.CalledOnValidThread()); 36 DCHECK(thread_checker_.CalledOnValidThread());
37 DCHECK(params.IsValid());
40 38
41 // Use the native audio output hardware sample-rate for the sink. 39 // Use the native audio output hardware sample-rate for the sink.
42 if (RenderThreadImpl::current()) { 40 if (RenderThreadImpl::current()) {
43 media::AudioHardwareConfig* hardware_config = 41 media::AudioHardwareConfig* hardware_config =
44 RenderThreadImpl::current()->GetAudioHardwareConfig(); 42 RenderThreadImpl::current()->GetAudioHardwareConfig();
45 int sample_rate = hardware_config->GetOutputSampleRate(); 43 int sample_rate = hardware_config->GetOutputSampleRate();
46 sink_params_.Reset( 44 sink_params_.Reset(
47 source_params.format(), media::CHANNEL_LAYOUT_STEREO, 2, 0, 45 params.format(), media::CHANNEL_LAYOUT_STEREO, 2, 0,
48 sample_rate, source_params.bits_per_sample(), 46 sample_rate, params.bits_per_sample(),
49 kWebAudioRenderBufferSize); 47 kWebAudioRenderBufferSize);
50 } else { 48 } else {
51 // This happens on unittests which does not have a valid RenderThreadImpl, 49 // This happens on unittests which does not have a valid RenderThreadImpl,
52 // the unittests should have injected their own |sink_params_| for testing. 50 // the unittests should have injected their own |sink_params_| for testing.
53 DCHECK(sink_params_.IsValid()); 51 DCHECK(sink_params_.IsValid());
54 } 52 }
55 53
56 base::AutoLock auto_lock(lock_); 54 base::AutoLock auto_lock(lock_);
57 source_params_ = source_params; 55 source_params_ = params;
58 // Create the audio converter with |disable_fifo| as false so that the 56 // Create the audio converter with |disable_fifo| as false so that the
59 // converter will request source_params.frames_per_buffer() each time. 57 // converter will request source_params.frames_per_buffer() each time.
60 // This will not increase the complexity as there is only one client to 58 // This will not increase the complexity as there is only one client to
61 // the converter. 59 // the converter.
62 audio_converter_.reset( 60 audio_converter_.reset(
63 new media::AudioConverter(source_params, sink_params_, false)); 61 new media::AudioConverter(params, sink_params_, false));
64 audio_converter_->AddInput(this); 62 audio_converter_->AddInput(this);
65 fifo_.reset(new media::AudioFifo( 63 fifo_.reset(new media::AudioFifo(
66 source_params.channels(), 64 params.channels(),
67 kMaxNumberOfBuffers * source_params.frames_per_buffer())); 65 kMaxNumberOfBuffers * params.frames_per_buffer()));
66 input_wrapper_ = media::AudioBus::Create(source_params_.channels(),
67 source_params_.frames_per_buffer());
68 } 68 }
69 69
70 void WebRtcLocalAudioSourceProvider::DeliverData( 70 int WebRtcLocalAudioSourceProvider::CaptureData(
71 media::AudioBus* audio_source, 71 const std::vector<int>& channels,
72 const int16* audio_data,
73 int sample_rate,
74 int number_of_channels,
75 int number_of_frames,
72 int audio_delay_milliseconds, 76 int audio_delay_milliseconds,
73 int volume, 77 int current_volume,
78 bool need_audio_processing,
74 bool key_pressed) { 79 bool key_pressed) {
75 base::AutoLock auto_lock(lock_); 80 base::AutoLock auto_lock(lock_);
76 if (!is_enabled_) 81 if (!is_enabled_)
77 return; 82 return 0;
78 83
79 DCHECK(fifo_.get()); 84 DCHECK(fifo_.get());
85 // TODO(xians): A better way to handle the interleaved and deinterleaved
86 // format switching.
87 DCHECK(input_wrapper_->frames() == number_of_frames);
88 CHECK(input_wrapper_->channels() == number_of_channels);
89 input_wrapper_->FromInterleaved(audio_data, number_of_frames, 2);
80 90
81 if (fifo_->frames() + audio_source->frames() <= fifo_->max_frames()) { 91 if (fifo_->frames() + number_of_frames <= fifo_->max_frames()) {
82 fifo_->Push(audio_source); 92 fifo_->Push(input_wrapper_.get());
83 } else { 93 } else {
84 // This can happen if the data in FIFO is too slowed to be consumed or 94 // This can happen if the data in FIFO is too slowed to be consumed or
85 // WebAudio stops consuming data. 95 // WebAudio stops consuming data.
86 DLOG(WARNING) << "Local source provicer FIFO is full" << fifo_->frames(); 96 DLOG(WARNING) << "Local source provicer FIFO is full" << fifo_->frames();
87 } 97 }
88 98
89 // Cache the values for GetAudioProcessingParams(). 99 return 0;
90 last_fill_ = base::TimeTicks::Now();
91 audio_delay_ms_ = audio_delay_milliseconds;
92 volume_ = volume;
93 key_pressed_ = key_pressed;
94 }
95
96 void WebRtcLocalAudioSourceProvider::GetAudioProcessingParams(
97 int* delay_ms, int* volume, bool* key_pressed) {
98 int elapsed_ms = 0;
99 if (!last_fill_.is_null()) {
100 elapsed_ms = static_cast<int>(
101 (base::TimeTicks::Now() - last_fill_).InMilliseconds());
102 }
103 *delay_ms = audio_delay_ms_ + elapsed_ms + static_cast<int>(
104 1000 * fifo_->frames() / source_params_.sample_rate() + 0.5);
105 *volume = volume_;
106 *key_pressed = key_pressed_;
107 } 100 }
108 101
109 void WebRtcLocalAudioSourceProvider::setClient( 102 void WebRtcLocalAudioSourceProvider::setClient(
110 WebKit::WebAudioSourceProviderClient* client) { 103 WebKit::WebAudioSourceProviderClient* client) {
111 NOTREACHED(); 104 NOTREACHED();
112 } 105 }
113 106
114 void WebRtcLocalAudioSourceProvider::provideInput( 107 void WebRtcLocalAudioSourceProvider::provideInput(
115 const WebVector<float*>& audio_data, size_t number_of_frames) { 108 const WebVector<float*>& audio_data, size_t number_of_frames) {
116 DCHECK_EQ(number_of_frames, kWebAudioRenderBufferSize); 109 DCHECK_EQ(number_of_frames, kWebAudioRenderBufferSize);
117 if (!bus_wrapper_ || 110 if (!output_wrapper_ ||
118 static_cast<size_t>(bus_wrapper_->channels()) != audio_data.size()) { 111 static_cast<size_t>(output_wrapper_->channels()) != audio_data.size()) {
119 bus_wrapper_ = media::AudioBus::CreateWrapper(audio_data.size()); 112 output_wrapper_ = media::AudioBus::CreateWrapper(audio_data.size());
120 } 113 }
121 114
122 bus_wrapper_->set_frames(number_of_frames); 115 output_wrapper_->set_frames(number_of_frames);
123 for (size_t i = 0; i < audio_data.size(); ++i) 116 for (size_t i = 0; i < audio_data.size(); ++i)
124 bus_wrapper_->SetChannelData(i, audio_data[i]); 117 output_wrapper_->SetChannelData(i, audio_data[i]);
125 118
126 base::AutoLock auto_lock(lock_); 119 base::AutoLock auto_lock(lock_);
127 DCHECK(audio_converter_.get()); 120 DCHECK(audio_converter_.get());
128 DCHECK(fifo_.get()); 121 DCHECK(fifo_.get());
129 is_enabled_ = true; 122 is_enabled_ = true;
130 audio_converter_->Convert(bus_wrapper_.get()); 123 audio_converter_->Convert(output_wrapper_.get());
131 } 124 }
132 125
133 double WebRtcLocalAudioSourceProvider::ProvideInput( 126 double WebRtcLocalAudioSourceProvider::ProvideInput(
134 media::AudioBus* audio_bus, base::TimeDelta buffer_delay) { 127 media::AudioBus* audio_bus, base::TimeDelta buffer_delay) {
135 if (fifo_->frames() >= audio_bus->frames()) { 128 if (fifo_->frames() >= audio_bus->frames()) {
136 fifo_->Consume(audio_bus, 0, audio_bus->frames()); 129 fifo_->Consume(audio_bus, 0, audio_bus->frames());
137 } else { 130 } else {
138 audio_bus->Zero(); 131 audio_bus->Zero();
139 if (!last_fill_.is_null()) { 132 DVLOG(1) << "WARNING: Underrun, FIFO has data " << fifo_->frames()
140 DLOG(WARNING) << "Underrun, FIFO has data " << fifo_->frames() 133 << " samples but " << audio_bus->frames()
141 << " samples but " << audio_bus->frames() 134 << " samples are needed";
142 << " samples are needed";
143 }
144 } 135 }
145 136
146 return 1.0; 137 return 1.0;
147 } 138 }
148 139
149 void WebRtcLocalAudioSourceProvider::SetSinkParamsForTesting( 140 void WebRtcLocalAudioSourceProvider::SetSinkParamsForTesting(
150 const media::AudioParameters& sink_params) { 141 const media::AudioParameters& sink_params) {
151 DCHECK(thread_checker_.CalledOnValidThread()); 142 DCHECK(thread_checker_.CalledOnValidThread());
152 sink_params_ = sink_params; 143 sink_params_ = sink_params;
153 } 144 }
154 145
155 } // namespace content 146 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698