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

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

Issue 23691038: Switch LiveAudio to source provider solution. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased and fixed some unittests Created 7 years, 3 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_audio_capturer.h" 5 #include "content/renderer/media/webrtc_audio_capturer.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/metrics/histogram.h" 9 #include "base/metrics/histogram.h"
10 #include "base/strings/string_util.h" 10 #include "base/strings/string_util.h"
11 #include "content/child/child_process.h" 11 #include "content/child/child_process.h"
12 #include "content/renderer/media/audio_device_factory.h" 12 #include "content/renderer/media/audio_device_factory.h"
13 #include "content/renderer/media/webrtc_audio_device_impl.h" 13 #include "content/renderer/media/webrtc_audio_device_impl.h"
14 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
14 #include "content/renderer/media/webrtc_local_audio_track.h" 15 #include "content/renderer/media/webrtc_local_audio_track.h"
16 #include "content/renderer/render_thread_impl.h"
15 #include "media/audio/audio_util.h" 17 #include "media/audio/audio_util.h"
16 #include "media/audio/sample_rates.h" 18 #include "media/audio/sample_rates.h"
19 #include "media/base/audio_hardware_config.h"
17 20
18 namespace content { 21 namespace content {
19 22
20 namespace { 23 namespace {
21 24
22 // Supported hardware sample rates for input and output sides. 25 // Supported hardware sample rates for input and output sides.
23 #if defined(OS_WIN) || defined(OS_MACOSX) 26 #if defined(OS_WIN) || defined(OS_MACOSX)
24 // media::GetAudioInputHardwareSampleRate() asks the audio layer 27 // media::GetAudioInputHardwareSampleRate() asks the audio layer
25 // for its current sample rate (set by the user) on Windows and Mac OS X. 28 // for its current sample rate (set by the user) on Windows and Mac OS X.
26 // The listed rates below adds restrictions and WebRtcAudioDeviceImpl::Init() 29 // The listed rates below adds restrictions and WebRtcAudioDeviceImpl::Init()
27 // will fail if the user selects any rate outside these ranges. 30 // will fail if the user selects any rate outside these ranges.
28 const int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000, 8000}; 31 const int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000, 8000};
29 #elif defined(OS_LINUX) || defined(OS_OPENBSD) 32 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
30 const int kValidInputRates[] = {48000, 44100}; 33 const int kValidInputRates[] = {48000, 44100};
31 #elif defined(OS_ANDROID) 34 #elif defined(OS_ANDROID)
32 const int kValidInputRates[] = {48000, 44100}; 35 const int kValidInputRates[] = {48000, 44100};
33 #else 36 #else
34 const int kValidInputRates[] = {44100}; 37 const int kValidInputRates[] = {44100};
35 #endif 38 #endif
36 39
37 int GetBufferSizeForSampleRate(int sample_rate) {
38 int buffer_size = 0;
39 #if defined(OS_WIN) || defined(OS_MACOSX)
40 // Use a buffer size of 10ms.
41 buffer_size = (sample_rate / 100);
42 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
43 // Based on tests using the current ALSA implementation in Chrome, we have
44 // found that the best combination is 20ms on the input side and 10ms on the
45 // output side.
46 buffer_size = 2 * sample_rate / 100;
47 #elif defined(OS_ANDROID)
48 // TODO(leozwang): Tune and adjust buffer size on Android.
49 buffer_size = 2 * sample_rate / 100;
50 #endif
51 return buffer_size;
52 }
53
54 } // namespace 40 } // namespace
55 41
56 // This is a temporary audio buffer with parameters used to send data to
57 // callbacks.
58 class WebRtcAudioCapturer::ConfiguredBuffer :
59 public base::RefCounted<WebRtcAudioCapturer::ConfiguredBuffer> {
60 public:
61 ConfiguredBuffer() {}
62
63 bool Initialize(int sample_rate,
64 media::ChannelLayout channel_layout) {
65 int buffer_size = GetBufferSizeForSampleRate(sample_rate);
66 DVLOG(1) << "Using WebRTC input buffer size: " << buffer_size;
67
68 media::AudioParameters::Format format =
69 media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
70
71 // bits_per_sample is always 16 for now.
72 int bits_per_sample = 16;
73 int channels = ChannelLayoutToChannelCount(channel_layout);
74 params_.Reset(format, channel_layout, channels, 0,
75 sample_rate, bits_per_sample, buffer_size);
76 buffer_.reset(new int16[params_.frames_per_buffer() * params_.channels()]);
77
78 return true;
79 }
80
81 int16* buffer() const { return buffer_.get(); }
82 const media::AudioParameters& params() const { return params_; }
83
84 private:
85 ~ConfiguredBuffer() {}
86 friend class base::RefCounted<WebRtcAudioCapturer::ConfiguredBuffer>;
87
88 scoped_ptr<int16[]> buffer_;
89
90 // Cached values of utilized audio parameters.
91 media::AudioParameters params_;
92 };
93
94 // Reference counted container of WebRtcLocalAudioTrack delegate. 42 // Reference counted container of WebRtcLocalAudioTrack delegate.
95 class WebRtcAudioCapturer::TrackOwner 43 class WebRtcAudioCapturer::TrackOwner
96 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> { 44 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> {
97 public: 45 public:
98 explicit TrackOwner(WebRtcLocalAudioTrack* track) 46 explicit TrackOwner(WebRtcLocalAudioTrack* track)
99 : delegate_(track) {} 47 : delegate_(track) {}
100 48
101 void CaptureData(const int16* audio_data, 49 void Capture(media::AudioBus* audio_source,
102 int number_of_channels, 50 int audio_delay_milliseconds,
103 int number_of_frames, 51 double volume,
104 int audio_delay_milliseconds, 52 bool key_pressed) {
105 int volume,
106 bool key_pressed) {
107 base::AutoLock lock(lock_); 53 base::AutoLock lock(lock_);
108 if (delegate_) { 54 if (delegate_) {
109 delegate_->CaptureData(audio_data, 55 delegate_->Capture(audio_source,
110 number_of_channels, 56 audio_delay_milliseconds,
111 number_of_frames, 57 volume,
112 audio_delay_milliseconds, 58 key_pressed);
113 volume,
114 key_pressed);
115 } 59 }
116 } 60 }
117 61
118 void SetCaptureFormat(const media::AudioParameters& params) { 62 void SetCaptureFormat(const media::AudioParameters& params) {
119 base::AutoLock lock(lock_); 63 base::AutoLock lock(lock_);
120 if (delegate_) 64 if (delegate_)
121 delegate_->SetCaptureFormat(params); 65 delegate_->SetCaptureFormat(params);
122 } 66 }
123 67
124 void Reset() { 68 void Reset() {
(...skipping 29 matching lines...) Expand all
154 98
155 DISALLOW_COPY_AND_ASSIGN(TrackOwner); 99 DISALLOW_COPY_AND_ASSIGN(TrackOwner);
156 }; 100 };
157 101
158 // static 102 // static
159 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer() { 103 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer() {
160 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer(); 104 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer();
161 return capturer; 105 return capturer;
162 } 106 }
163 107
164 bool WebRtcAudioCapturer::Reconfigure(int sample_rate, 108 void WebRtcAudioCapturer::Reconfigure(int sample_rate,
165 media::ChannelLayout channel_layout) { 109 media::ChannelLayout channel_layout) {
166 scoped_refptr<ConfiguredBuffer> new_buffer(new ConfiguredBuffer()); 110 DCHECK(thread_checker_.CalledOnValidThread());
167 if (!new_buffer->Initialize(sample_rate, channel_layout)) 111 int buffer_size = GetBufferSize(sample_rate);
168 return false; 112 DVLOG(1) << "Using WebRTC input buffer size: " << buffer_size;
113
114 media::AudioParameters::Format format =
115 media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
116
117 // bits_per_sample is always 16 for now.
118 int bits_per_sample = 16;
119 media::AudioParameters params(format, channel_layout, sample_rate,
120 bits_per_sample, buffer_size);
169 121
170 TrackList tracks; 122 TrackList tracks;
171 { 123 {
172 base::AutoLock auto_lock(lock_); 124 base::AutoLock auto_lock(lock_);
173
174 buffer_ = new_buffer;
175 tracks = tracks_; 125 tracks = tracks_;
126 params_ = params;
176 } 127 }
177 128
178 // Tell all audio_tracks which format we use. 129 // Tell all audio_tracks which format we use.
179 for (TrackList::const_iterator it = tracks.begin(); 130 for (TrackList::const_iterator it = tracks.begin();
180 it != tracks.end(); ++it) 131 it != tracks.end(); ++it)
181 (*it)->SetCaptureFormat(new_buffer->params()); 132 (*it)->SetCaptureFormat(params);
182
183 return true;
184 } 133 }
185 134
186 bool WebRtcAudioCapturer::Initialize(int render_view_id, 135 bool WebRtcAudioCapturer::Initialize(int render_view_id,
187 media::ChannelLayout channel_layout, 136 media::ChannelLayout channel_layout,
188 int sample_rate, 137 int sample_rate,
189 int session_id, 138 int session_id,
190 const std::string& device_id) { 139 const std::string& device_id) {
191 DCHECK(thread_checker_.CalledOnValidThread()); 140 DCHECK(thread_checker_.CalledOnValidThread());
141 DCHECK_GE(render_view_id, 0);
192 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; 142 DVLOG(1) << "WebRtcAudioCapturer::Initialize()";
193 143
194 DVLOG(1) << "Audio input hardware channel layout: " << channel_layout; 144 DVLOG(1) << "Audio input hardware channel layout: " << channel_layout;
195 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputChannelLayout", 145 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputChannelLayout",
196 channel_layout, media::CHANNEL_LAYOUT_MAX); 146 channel_layout, media::CHANNEL_LAYOUT_MAX);
197 147
148 render_view_id_ = render_view_id;
198 session_id_ = session_id; 149 session_id_ = session_id;
199 device_id_ = device_id; 150 device_id_ = device_id;
151
200 if (render_view_id == -1) { 152 if (render_view_id == -1) {
tommi (sloooow) - chröme 2013/09/06 11:20:30 this should never happen now that you've added the
no longer working on chromium 2013/09/10 12:43:15 This happens and is needed for testing cases. Also
201 // This capturer is used by WebAudio, return true without creating a 153 // Return true here to allow injecting a new source via SetCapturerSource()
202 // default capturing source. WebAudio will inject its own source via 154 // at a later state.
203 // SetCapturerSource() at a later state.
204 DCHECK(device_id.empty());
205 return true; 155 return true;
206 } 156 }
207 157
208 // Verify that the reported input channel configuration is supported. 158 // Verify that the reported input channel configuration is supported.
209 if (channel_layout != media::CHANNEL_LAYOUT_MONO && 159 if (channel_layout != media::CHANNEL_LAYOUT_MONO &&
210 channel_layout != media::CHANNEL_LAYOUT_STEREO) { 160 channel_layout != media::CHANNEL_LAYOUT_STEREO) {
211 DLOG(ERROR) << channel_layout 161 DLOG(ERROR) << channel_layout
212 << " is not a supported input channel configuration."; 162 << " is not a supported input channel configuration.";
213 return false; 163 return false;
214 } 164 }
(...skipping 10 matching lines...) Expand all
225 // Verify that the reported input hardware sample rate is supported 175 // Verify that the reported input hardware sample rate is supported
226 // on the current platform. 176 // on the current platform.
227 if (std::find(&kValidInputRates[0], 177 if (std::find(&kValidInputRates[0],
228 &kValidInputRates[0] + arraysize(kValidInputRates), 178 &kValidInputRates[0] + arraysize(kValidInputRates),
229 sample_rate) == 179 sample_rate) ==
230 &kValidInputRates[arraysize(kValidInputRates)]) { 180 &kValidInputRates[arraysize(kValidInputRates)]) {
231 DLOG(ERROR) << sample_rate << " is not a supported input rate."; 181 DLOG(ERROR) << sample_rate << " is not a supported input rate.";
232 return false; 182 return false;
233 } 183 }
234 184
235 if (!Reconfigure(sample_rate, channel_layout)) 185 Reconfigure(sample_rate, channel_layout);
236 return false;
237 186
238 // Create and configure the default audio capturing source. The |source_| 187 // Create and configure the default audio capturing source. The |source_|
239 // will be overwritten if an external client later calls SetCapturerSource() 188 // will be overwritten if an external client later calls SetCapturerSource()
240 // providing an alternative media::AudioCapturerSource. 189 // providing an alternative media::AudioCapturerSource.
241 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id), 190 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id),
242 channel_layout, 191 channel_layout,
243 static_cast<float>(sample_rate)); 192 static_cast<float>(sample_rate));
244 193
245 return true; 194 return true;
246 } 195 }
247 196
248 WebRtcAudioCapturer::WebRtcAudioCapturer() 197 WebRtcAudioCapturer::WebRtcAudioCapturer()
249 : source_(NULL), 198 : source_(NULL),
250 running_(false), 199 running_(false),
251 agc_is_enabled_(false), 200 agc_is_enabled_(false),
201 render_view_id_(-1),
252 session_id_(0), 202 session_id_(0),
253 volume_(0) { 203 volume_(0),
204 source_provider_(new WebRtcLocalAudioSourceProvider()),
205 peer_connection_mode_(false) {
206 DCHECK(source_provider_.get());
254 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; 207 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()";
255 } 208 }
256 209
257 WebRtcAudioCapturer::~WebRtcAudioCapturer() { 210 WebRtcAudioCapturer::~WebRtcAudioCapturer() {
258 DCHECK(thread_checker_.CalledOnValidThread()); 211 DCHECK(thread_checker_.CalledOnValidThread());
259 DCHECK(tracks_.empty()); 212 DCHECK(tracks_.empty());
260 DCHECK(!running_); 213 DCHECK(!running_);
261 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; 214 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()";
262 } 215 }
263 216
264 void WebRtcAudioCapturer::AddTrack(WebRtcLocalAudioTrack* track) { 217 void WebRtcAudioCapturer::AddTrack(WebRtcLocalAudioTrack* track) {
265 DCHECK(track); 218 DCHECK(track);
266 DVLOG(1) << "WebRtcAudioCapturer::AddTrack()"; 219 DVLOG(1) << "WebRtcAudioCapturer::AddTrack()";
267 220
268 // Start the source if the first audio track is connected to the capturer. 221 // Start the source if the first audio track is connected to the capturer.
269 // Start() will do nothing if the capturer has already been started. 222 // Start() will do nothing if the capturer has already been started.
270 Start(); 223 Start();
271 224
272 base::AutoLock auto_lock(lock_); 225 base::AutoLock auto_lock(lock_);
273 // Verify that |track| is not already added to the list. 226 // Verify that |track| is not already added to the list.
274 DCHECK(std::find_if(tracks_.begin(), tracks_.end(), 227 DCHECK(std::find_if(tracks_.begin(), tracks_.end(),
275 TrackOwner::TrackWrapper(track)) == tracks_.end()); 228 TrackOwner::TrackWrapper(track)) == tracks_.end());
276 229
277 if (buffer_.get()) { 230 track->SetCaptureFormat(params_);
278 track->SetCaptureFormat(buffer_->params());
279 }
280
281 tracks_.push_back(new WebRtcAudioCapturer::TrackOwner(track)); 231 tracks_.push_back(new WebRtcAudioCapturer::TrackOwner(track));
282 } 232 }
283 233
284 void WebRtcAudioCapturer::RemoveTrack(WebRtcLocalAudioTrack* track) { 234 void WebRtcAudioCapturer::RemoveTrack(WebRtcLocalAudioTrack* track) {
285 DCHECK(thread_checker_.CalledOnValidThread()); 235 DCHECK(thread_checker_.CalledOnValidThread());
286 236
287 bool stop_source = false; 237 bool stop_source = false;
288 { 238 {
289 base::AutoLock auto_lock(lock_); 239 base::AutoLock auto_lock(lock_);
290 // Get iterator to the first element for which WrapsSink(track) returns 240 // Get iterator to the first element for which WrapsSink(track) returns
(...skipping 17 matching lines...) Expand all
308 } 258 }
309 259
310 void WebRtcAudioCapturer::SetCapturerSource( 260 void WebRtcAudioCapturer::SetCapturerSource(
311 const scoped_refptr<media::AudioCapturerSource>& source, 261 const scoped_refptr<media::AudioCapturerSource>& source,
312 media::ChannelLayout channel_layout, 262 media::ChannelLayout channel_layout,
313 float sample_rate) { 263 float sample_rate) {
314 DCHECK(thread_checker_.CalledOnValidThread()); 264 DCHECK(thread_checker_.CalledOnValidThread());
315 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," 265 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << ","
316 << "sample_rate=" << sample_rate << ")"; 266 << "sample_rate=" << sample_rate << ")";
317 scoped_refptr<media::AudioCapturerSource> old_source; 267 scoped_refptr<media::AudioCapturerSource> old_source;
318 scoped_refptr<ConfiguredBuffer> current_buffer;
319 bool restart_source = false; 268 bool restart_source = false;
320 { 269 {
321 base::AutoLock auto_lock(lock_); 270 base::AutoLock auto_lock(lock_);
322 if (source_.get() == source.get()) 271 if (source_.get() == source.get())
323 return; 272 return;
324 273
325 source_.swap(old_source); 274 source_.swap(old_source);
326 source_ = source; 275 source_ = source;
327 current_buffer = buffer_;
328 276
329 // Reset the flag to allow starting the new source. 277 // Reset the flag to allow starting the new source.
330 restart_source = running_; 278 restart_source = running_;
331 running_ = false; 279 running_ = false;
332 } 280 }
333 281
334 const bool no_default_audio_source_exists = !current_buffer.get();
335 282
336 // Detach the old source from normal recording or perform first-time 283 DVLOG(1) << "New capture source will now be utilized.";
tommi (sloooow) - chröme 2013/09/06 11:20:30 s/utilized/used suggest "Switching to a new captur
no longer working on chromium 2013/09/10 12:43:15 Done.
337 // initialization if Initialize() has never been called. For the second 284 if (old_source.get())
338 // case, the caller is not "taking over an ongoing session" but instead 285 old_source->Stop();
339 // "taking control over a new session".
340 if (old_source.get() || no_default_audio_source_exists) {
341 DVLOG(1) << "New capture source will now be utilized.";
342 if (old_source.get())
343 old_source->Stop();
344 286
345 // Dispatch the new parameters both to the sink(s) and to the new source. 287 // Dispatch the new parameters both to the sink(s) and to the new source.
346 // The idea is to get rid of any dependency of the microphone parameters 288 // The idea is to get rid of any dependency of the microphone parameters
347 // which would normally be used by default. 289 // which would normally be used by default.
348 if (!Reconfigure(sample_rate, channel_layout)) { 290 Reconfigure(sample_rate, channel_layout);
349 return;
350 } else {
351 // The buffer has been reconfigured. Update |current_buffer|.
352 base::AutoLock auto_lock(lock_);
353 current_buffer = buffer_;
354 }
355 }
356 291
357 if (source.get()) { 292 // Make sure to grab the new parameters in case they were reconfigured.
358 // Make sure to grab the new parameters in case they were reconfigured. 293 media::AudioParameters params = audio_parameters();
359 source->Initialize(current_buffer->params(), this, session_id_); 294 source_provider_->Initialize(params);
360 } 295 if (source.get())
296 source->Initialize(params, this, session_id_);
361 297
362 if (restart_source) 298 if (restart_source)
363 Start(); 299 Start();
364 } 300 }
365 301
302 void WebRtcAudioCapturer::EnablePeerConnectionMode() {
303 DCHECK(thread_checker_.CalledOnValidThread());
304 DVLOG(1) << "EnablePeerConnectionMode";
305 // Do nothing if the native mode has been enabled.
tommi (sloooow) - chröme 2013/09/06 11:20:30 s/the native mode/peer connection mode (or just re
no longer working on chromium 2013/09/10 12:43:15 Done.
306 if (peer_connection_mode_)
307 return;
308
309 DLOG(WARNING) << "EnablePeerConnectionMode";
tommi (sloooow) - chröme 2013/09/06 11:20:30 Remove?
no longer working on chromium 2013/09/10 12:43:15 Done.
310 peer_connection_mode_ = true;
311
312 {
313 base::AutoLock auto_lock(lock_);
314 // Simply return if there is no existing source or the |render_view_id_| is
315 // not valid.
316 if (!source_.get() || render_view_id_== -1)
317 return;
318 }
319
320 // Create a new audio stream as source which will open the hardware using
321 // WebRtc native buffer size.
322 media::AudioParameters params = audio_parameters();
323 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id_),
tommi (sloooow) - chröme 2013/09/06 11:20:30 Since you're no longer under the lock, is it possi
no longer working on chromium 2013/09/10 12:43:15 SetCapturerSource() can't be called under a lock s
324 params.channel_layout(),
325 static_cast<float>(params.sample_rate()));
tommi (sloooow) - chröme 2013/09/06 11:20:30 why are we using float for the sample rate?
no longer working on chromium 2013/09/10 12:43:15 Just chatted with Henrik on this, it is simply som
326 }
327
366 void WebRtcAudioCapturer::Start() { 328 void WebRtcAudioCapturer::Start() {
367 DVLOG(1) << "WebRtcAudioCapturer::Start()"; 329 DVLOG(1) << "WebRtcAudioCapturer::Start()";
368 base::AutoLock auto_lock(lock_); 330 base::AutoLock auto_lock(lock_);
369 if (running_) 331 if (running_)
370 return; 332 return;
371 333
372 // Start the data source, i.e., start capturing data from the current source. 334 // Start the data source, i.e., start capturing data from the current source.
373 // Note that, the source does not have to be a microphone. 335 // Note that, the source does not have to be a microphone.
374 if (source_.get()) { 336 if (source_.get()) {
375 // We need to set the AGC control before starting the stream. 337 // We need to set the AGC control before starting the stream.
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
436 #elif defined(OS_LINUX) || defined(OS_OPENBSD) 398 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
437 // We have a special situation on Linux where the microphone volume can be 399 // We have a special situation on Linux where the microphone volume can be
438 // "higher than maximum". The input volume slider in the sound preference 400 // "higher than maximum". The input volume slider in the sound preference
439 // allows the user to set a scaling that is higher than 100%. It means that 401 // allows the user to set a scaling that is higher than 100%. It means that
440 // even if the reported maximum levels is N, the actual microphone level can 402 // even if the reported maximum levels is N, the actual microphone level can
441 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x. 403 // go up to 1.5x*N and that corresponds to a normalized |volume| of 1.5x.
442 DCHECK_LE(volume, 1.6); 404 DCHECK_LE(volume, 1.6);
443 #endif 405 #endif
444 406
445 TrackList tracks; 407 TrackList tracks;
446 scoped_refptr<ConfiguredBuffer> buffer_ref_while_calling; 408 int current_volume = 0;
447 { 409 {
448 base::AutoLock auto_lock(lock_); 410 base::AutoLock auto_lock(lock_);
449 if (!running_) 411 if (!running_)
450 return; 412 return;
451 413
452 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the 414 // Map internal volume range of [0.0, 1.0] into [0, 255] used by the
453 // webrtc::VoiceEngine. webrtc::VoiceEngine will handle the case when the 415 // webrtc::VoiceEngine. webrtc::VoiceEngine will handle the case when the
454 // volume is higher than 255. 416 // volume is higher than 255.
455 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5); 417 volume_ = static_cast<int>((volume * MaxVolume()) + 0.5);
456 418 current_volume = volume_;
457 // Copy the stuff we will need to local variables. In particular, we grab
458 // a reference to the buffer so we can ensure it stays alive even if the
459 // buffer is reconfigured while we are calling back.
460 buffer_ref_while_calling = buffer_;
461 tracks = tracks_; 419 tracks = tracks_;
462 } 420 }
463 421
464 int bytes_per_sample = 422 // Deliver captured data to source provider, which stores the data into FIFO
465 buffer_ref_while_calling->params().bits_per_sample() / 8; 423 // for WebAudio to fetch.
466 424 source_provider_->DeliverData(audio_source, audio_delay_milliseconds,
467 // Interleave, scale, and clip input to int and store result in 425 current_volume, key_pressed);
468 // a local byte buffer.
469 audio_source->ToInterleaved(audio_source->frames(), bytes_per_sample,
470 buffer_ref_while_calling->buffer());
471 426
472 // Feed the data to the tracks. 427 // Feed the data to the tracks.
473 for (TrackList::const_iterator it = tracks.begin(); 428 for (TrackList::const_iterator it = tracks.begin();
474 it != tracks.end(); 429 it != tracks.end();
475 ++it) { 430 ++it) {
476 (*it)->CaptureData(buffer_ref_while_calling->buffer(), 431 (*it)->Capture(audio_source, audio_delay_milliseconds,
477 audio_source->channels(), 432 current_volume, key_pressed);
478 audio_source->frames(),
479 audio_delay_milliseconds,
480 volume,
481 key_pressed);
482 } 433 }
483 } 434 }
484 435
485 void WebRtcAudioCapturer::OnCaptureError() { 436 void WebRtcAudioCapturer::OnCaptureError() {
486 NOTIMPLEMENTED(); 437 NOTIMPLEMENTED();
487 } 438 }
488 439
489 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { 440 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const {
490 base::AutoLock auto_lock(lock_); 441 base::AutoLock auto_lock(lock_);
491 // |buffer_| can be NULL when SetCapturerSource() or Initialize() has not 442 return params_;
492 // been called. 443 }
493 return buffer_.get() ? buffer_->params() : media::AudioParameters(); 444
445 WebKit::WebAudioSourceProvider*
446 WebRtcAudioCapturer::AudioSourceProvider() const {
447 return source_provider_.get();
tommi (sloooow) - chröme 2013/09/06 11:20:30 since we never change the value of source_provider
no longer working on chromium 2013/09/10 12:43:15 Done with changing the source_provider_ to be cons
448 }
449
450 int WebRtcAudioCapturer::GetBufferSize(int sample_rate) const {
451 #if defined(OS_ANDROID)
452 // TODO(leozwang): Tune and adjust buffer size on Android.
453 return (2 * sample_rate / 100);
454 #endif
455 DLOG(WARNING) << "GetBufferSize " << peer_connection_mode_;
tommi (sloooow) - chröme 2013/09/06 11:20:30 remove?
no longer working on chromium 2013/09/10 12:43:15 Done.
456 if (peer_connection_mode_) {
tommi (sloooow) - chröme 2013/09/06 11:20:30 before checking this, should we grab the lock? (o
no longer working on chromium 2013/09/10 12:43:15 Done with adding a thread check.
457 // WebRtc is running at a buffer size of 10ms data. Use a multiple of 10ms
458 // as the buffer size to achieve the best performance for WebRtc.
459 return (sample_rate / 100);
460 }
461
462 // Use the native hardware buffer size.
463 media::AudioHardwareConfig* hardware_config =
464 RenderThreadImpl::current()->GetAudioHardwareConfig();
465 return hardware_config->GetInputBufferSize();
494 } 466 }
495 467
496 } // namespace content 468 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698