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

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: addressed Tommi's comments and added unittest 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"
(...skipping 16 matching lines...) Expand all
27 // will fail if the user selects any rate outside these ranges. 27 // will fail if the user selects any rate outside these ranges.
28 const int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000, 8000}; 28 const int kValidInputRates[] = {96000, 48000, 44100, 32000, 16000, 8000};
29 #elif defined(OS_LINUX) || defined(OS_OPENBSD) 29 #elif defined(OS_LINUX) || defined(OS_OPENBSD)
30 const int kValidInputRates[] = {48000, 44100}; 30 const int kValidInputRates[] = {48000, 44100};
31 #elif defined(OS_ANDROID) 31 #elif defined(OS_ANDROID)
32 const int kValidInputRates[] = {48000, 44100}; 32 const int kValidInputRates[] = {48000, 44100};
33 #else 33 #else
34 const int kValidInputRates[] = {44100}; 34 const int kValidInputRates[] = {44100};
35 #endif 35 #endif
36 36
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 37 } // namespace
55 38
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. 39 // Reference counted container of WebRtcLocalAudioTrack delegate.
95 class WebRtcAudioCapturer::TrackOwner 40 class WebRtcAudioCapturer::TrackOwner
96 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> { 41 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> {
97 public: 42 public:
98 explicit TrackOwner(WebRtcLocalAudioTrack* track) 43 explicit TrackOwner(WebRtcLocalAudioTrack* track)
99 : delegate_(track) {} 44 : delegate_(track) {}
100 45
101 void CaptureData(const int16* audio_data, 46 void Capture(media::AudioBus* audio_source,
102 int number_of_channels, 47 int audio_delay_milliseconds,
103 int number_of_frames, 48 double volume,
104 int audio_delay_milliseconds, 49 bool key_pressed) {
105 int volume,
106 bool key_pressed) {
107 base::AutoLock lock(lock_); 50 base::AutoLock lock(lock_);
108 if (delegate_) { 51 if (delegate_) {
109 delegate_->CaptureData(audio_data, 52 delegate_->Capture(audio_source,
110 number_of_channels, 53 audio_delay_milliseconds,
111 number_of_frames, 54 volume,
112 audio_delay_milliseconds, 55 key_pressed);
113 volume,
114 key_pressed);
115 } 56 }
116 } 57 }
117 58
118 void SetCaptureFormat(const media::AudioParameters& params) { 59 void SetCaptureFormat(const media::AudioParameters& params) {
119 base::AutoLock lock(lock_); 60 base::AutoLock lock(lock_);
120 if (delegate_) 61 if (delegate_)
121 delegate_->SetCaptureFormat(params); 62 delegate_->SetCaptureFormat(params);
122 } 63 }
123 64
124 void Reset() { 65 void Reset() {
(...skipping 29 matching lines...) Expand all
154 95
155 DISALLOW_COPY_AND_ASSIGN(TrackOwner); 96 DISALLOW_COPY_AND_ASSIGN(TrackOwner);
156 }; 97 };
157 98
158 // static 99 // static
159 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer() { 100 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer() {
160 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer(); 101 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer();
161 return capturer; 102 return capturer;
162 } 103 }
163 104
164 bool WebRtcAudioCapturer::Reconfigure(int sample_rate, 105 void WebRtcAudioCapturer::Reconfigure(int sample_rate,
165 media::ChannelLayout channel_layout) { 106 media::ChannelLayout channel_layout) {
166 scoped_refptr<ConfiguredBuffer> new_buffer(new ConfiguredBuffer()); 107 DCHECK(thread_checker_.CalledOnValidThread());
167 if (!new_buffer->Initialize(sample_rate, channel_layout)) 108 int buffer_size = GetBufferSize(sample_rate);
168 return false; 109 DVLOG(1) << "Using WebRTC input buffer size: " << buffer_size;
110
111 media::AudioParameters::Format format =
112 media::AudioParameters::AUDIO_PCM_LOW_LATENCY;
113
114 // bits_per_sample is always 16 for now.
115 int bits_per_sample = 16;
116 media::AudioParameters params(format, channel_layout, sample_rate,
117 bits_per_sample, buffer_size);
169 118
170 TrackList tracks; 119 TrackList tracks;
171 { 120 {
172 base::AutoLock auto_lock(lock_); 121 base::AutoLock auto_lock(lock_);
173
174 buffer_ = new_buffer;
175 tracks = tracks_; 122 tracks = tracks_;
123 params_ = params;
176 } 124 }
177 125
178 // Tell all audio_tracks which format we use. 126 // Tell all audio_tracks which format we use.
179 for (TrackList::const_iterator it = tracks.begin(); 127 for (TrackList::const_iterator it = tracks.begin();
180 it != tracks.end(); ++it) 128 it != tracks.end(); ++it)
181 (*it)->SetCaptureFormat(new_buffer->params()); 129 (*it)->SetCaptureFormat(params);
182
183 return true;
184 } 130 }
185 131
186 bool WebRtcAudioCapturer::Initialize(int render_view_id, 132 bool WebRtcAudioCapturer::Initialize(int render_view_id,
187 media::ChannelLayout channel_layout, 133 media::ChannelLayout channel_layout,
188 int sample_rate, 134 int sample_rate,
135 int buffer_size,
189 int session_id, 136 int session_id,
190 const std::string& device_id) { 137 const std::string& device_id) {
191 DCHECK(thread_checker_.CalledOnValidThread()); 138 DCHECK(thread_checker_.CalledOnValidThread());
139 DCHECK_GE(render_view_id, 0);
192 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; 140 DVLOG(1) << "WebRtcAudioCapturer::Initialize()";
193 141
194 DVLOG(1) << "Audio input hardware channel layout: " << channel_layout; 142 DVLOG(1) << "Audio input hardware channel layout: " << channel_layout;
195 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputChannelLayout", 143 UMA_HISTOGRAM_ENUMERATION("WebRTC.AudioInputChannelLayout",
196 channel_layout, media::CHANNEL_LAYOUT_MAX); 144 channel_layout, media::CHANNEL_LAYOUT_MAX);
197 145
146 render_view_id_ = render_view_id;
198 session_id_ = session_id; 147 session_id_ = session_id;
199 device_id_ = device_id; 148 device_id_ = device_id;
149 hardware_buffer_size_ = buffer_size;
150
200 if (render_view_id == -1) { 151 if (render_view_id == -1) {
201 // This capturer is used by WebAudio, return true without creating a 152 // Return true here to allow injecting a new source via SetCapturerSource()
202 // default capturing source. WebAudio will inject its own source via 153 // at a later state.
203 // SetCapturerSource() at a later state.
204 DCHECK(device_id.empty());
205 return true; 154 return true;
206 } 155 }
207 156
208 // Verify that the reported input channel configuration is supported. 157 // Verify that the reported input channel configuration is supported.
209 if (channel_layout != media::CHANNEL_LAYOUT_MONO && 158 if (channel_layout != media::CHANNEL_LAYOUT_MONO &&
210 channel_layout != media::CHANNEL_LAYOUT_STEREO) { 159 channel_layout != media::CHANNEL_LAYOUT_STEREO) {
211 DLOG(ERROR) << channel_layout 160 DLOG(ERROR) << channel_layout
212 << " is not a supported input channel configuration."; 161 << " is not a supported input channel configuration.";
213 return false; 162 return false;
214 } 163 }
(...skipping 10 matching lines...) Expand all
225 // Verify that the reported input hardware sample rate is supported 174 // Verify that the reported input hardware sample rate is supported
226 // on the current platform. 175 // on the current platform.
227 if (std::find(&kValidInputRates[0], 176 if (std::find(&kValidInputRates[0],
228 &kValidInputRates[0] + arraysize(kValidInputRates), 177 &kValidInputRates[0] + arraysize(kValidInputRates),
229 sample_rate) == 178 sample_rate) ==
230 &kValidInputRates[arraysize(kValidInputRates)]) { 179 &kValidInputRates[arraysize(kValidInputRates)]) {
231 DLOG(ERROR) << sample_rate << " is not a supported input rate."; 180 DLOG(ERROR) << sample_rate << " is not a supported input rate.";
232 return false; 181 return false;
233 } 182 }
234 183
235 if (!Reconfigure(sample_rate, channel_layout)) 184 Reconfigure(sample_rate, channel_layout);
236 return false;
237 185
238 // Create and configure the default audio capturing source. The |source_| 186 // Create and configure the default audio capturing source. The |source_|
239 // will be overwritten if an external client later calls SetCapturerSource() 187 // will be overwritten if an external client later calls SetCapturerSource()
240 // providing an alternative media::AudioCapturerSource. 188 // providing an alternative media::AudioCapturerSource.
241 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id), 189 SetCapturerSource(AudioDeviceFactory::NewInputDevice(render_view_id),
242 channel_layout, 190 channel_layout,
243 static_cast<float>(sample_rate)); 191 static_cast<float>(sample_rate));
244 192
245 return true; 193 return true;
246 } 194 }
247 195
248 WebRtcAudioCapturer::WebRtcAudioCapturer() 196 WebRtcAudioCapturer::WebRtcAudioCapturer()
249 : source_(NULL), 197 : source_(NULL),
250 running_(false), 198 running_(false),
251 agc_is_enabled_(false), 199 agc_is_enabled_(false),
200 render_view_id_(-1),
201 hardware_buffer_size_(0),
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(); 282 DVLOG(1) << "Switching to a new capture source.";
283 if (old_source.get())
284 old_source->Stop();
335 285
336 // Detach the old source from normal recording or perform first-time 286 // Dispatch the new parameters both to the sink(s) and to the new source.
337 // initialization if Initialize() has never been called. For the second 287 // The idea is to get rid of any dependency of the microphone parameters
338 // case, the caller is not "taking over an ongoing session" but instead 288 // which would normally be used by default.
339 // "taking control over a new session". 289 Reconfigure(sample_rate, channel_layout);
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 290
345 // Dispatch the new parameters both to the sink(s) and to the new source. 291 // Make sure to grab the new parameters in case they were reconfigured.
346 // The idea is to get rid of any dependency of the microphone parameters 292 media::AudioParameters params = audio_parameters();
347 // which would normally be used by default. 293 source_provider_->Initialize(params);
348 if (!Reconfigure(sample_rate, channel_layout)) { 294 if (source.get())
349 return; 295 source->Initialize(params, this, session_id_);
350 } else {
351 // The buffer has been reconfigured. Update |current_buffer|.
352 base::AutoLock auto_lock(lock_);
353 current_buffer = buffer_;
354 }
355 }
356
357 if (source.get()) {
358 // Make sure to grab the new parameters in case they were reconfigured.
359 source->Initialize(current_buffer->params(), this, session_id_);
360 }
361 296
362 if (restart_source) 297 if (restart_source)
363 Start(); 298 Start();
364 } 299 }
365 300
301 void WebRtcAudioCapturer::EnablePeerConnectionMode() {
302 DCHECK(thread_checker_.CalledOnValidThread());
303 DVLOG(1) << "EnablePeerConnectionMode";
304 // Do nothing if the peer connection mode has been enabled.
305 if (peer_connection_mode_)
306 return;
307
308 peer_connection_mode_ = true;
309 int render_view_id = -1;
310 {
311 base::AutoLock auto_lock(lock_);
312 // Simply return if there is no existing source or the |render_view_id_| is
313 // not valid.
314 if (!source_.get() || render_view_id_== -1)
315 return;
316
317 render_view_id = render_view_id_;
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),
324 params.channel_layout(),
325 static_cast<float>(params.sample_rate()));
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 int WebRtcAudioCapturer::GetBufferSize(int sample_rate) const {
446 DCHECK(thread_checker_.CalledOnValidThread());
447 #if defined(OS_ANDROID)
448 // TODO(leozwang): Tune and adjust buffer size on Android.
tommi (sloooow) - chröme 2013/09/10 16:00:38 can you assign this to henrika instead?
no longer working on chromium 2013/09/11 10:22:07 Done.
449 return (2 * sample_rate / 100);
450 #endif
451
452 // Use the native hardware buffer size in non peer connection mode.
453 if (!peer_connection_mode_ && hardware_buffer_size_)
454 return hardware_buffer_size_;
455
456 // WebRtc is running at a buffer size of 10ms data. Use a multiple of 10ms
457 // as the buffer size to achieve the best performance for WebRtc.
458 return (sample_rate / 100);
494 } 459 }
495 460
496 } // namespace content 461 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698