| OLD | NEW |
| 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/string_util.h" | 10 #include "base/string_util.h" |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 static int kValidInputRates[] = {48000, 44100}; | 28 static int kValidInputRates[] = {48000, 44100}; |
| 29 #elif defined(OS_ANDROID) | 29 #elif defined(OS_ANDROID) |
| 30 static int kValidInputRates[] = {48000, 44100}; | 30 static int kValidInputRates[] = {48000, 44100}; |
| 31 #else | 31 #else |
| 32 static int kValidInputRates[] = {44100}; | 32 static int kValidInputRates[] = {44100}; |
| 33 #endif | 33 #endif |
| 34 | 34 |
| 35 static int GetBufferSizeForSampleRate(int sample_rate) { | 35 static int GetBufferSizeForSampleRate(int sample_rate) { |
| 36 int buffer_size = 0; | 36 int buffer_size = 0; |
| 37 #if defined(OS_WIN) || defined(OS_MACOSX) | 37 #if defined(OS_WIN) || defined(OS_MACOSX) |
| 38 // Use different buffer sizes depending on the current hardware sample rate. | 38 // Use a buffer size of 10ms. |
| 39 if (sample_rate == 44100) { | 39 buffer_size = (sample_rate / 100); |
| 40 // We do run at 44.1kHz at the actual audio layer, but ask for frames | |
| 41 // at 44.0kHz to ensure that we can feed them to the webrtc::VoiceEngine. | |
| 42 buffer_size = 440; | |
| 43 } else { | |
| 44 buffer_size = (sample_rate / 100); | |
| 45 DCHECK_EQ(buffer_size * 100, sample_rate) << | |
| 46 "Sample rate not supported"; | |
| 47 } | |
| 48 #elif defined(OS_LINUX) || defined(OS_OPENBSD) | 40 #elif defined(OS_LINUX) || defined(OS_OPENBSD) |
| 49 // Based on tests using the current ALSA implementation in Chrome, we have | 41 // Based on tests using the current ALSA implementation in Chrome, we have |
| 50 // found that the best combination is 20ms on the input side and 10ms on the | 42 // found that the best combination is 20ms on the input side and 10ms on the |
| 51 // output side. | 43 // output side. |
| 52 // TODO(henrika): It might be possible to reduce the input buffer | 44 buffer_size = 2 * sample_rate / 100; |
| 53 // size and reduce the delay even more. | |
| 54 if (sample_rate == 44100) | |
| 55 buffer_size = 2 * 440; | |
| 56 else | |
| 57 buffer_size = 2 * sample_rate / 100; | |
| 58 #elif defined(OS_ANDROID) | 45 #elif defined(OS_ANDROID) |
| 59 // TODO(leozwang): Tune and adjust buffer size on Android. | 46 // TODO(leozwang): Tune and adjust buffer size on Android. |
| 60 if (sample_rate == 44100) | |
| 61 buffer_size = 2 * 440; | |
| 62 else | |
| 63 buffer_size = 2 * sample_rate / 100; | 47 buffer_size = 2 * sample_rate / 100; |
| 64 #endif | 48 #endif |
| 65 | |
| 66 return buffer_size; | 49 return buffer_size; |
| 67 } | 50 } |
| 68 | 51 |
| 69 // This is a temporary audio buffer with parameters used to send data to | 52 // This is a temporary audio buffer with parameters used to send data to |
| 70 // callbacks. | 53 // callbacks. |
| 71 class WebRtcAudioCapturer::ConfiguredBuffer : | 54 class WebRtcAudioCapturer::ConfiguredBuffer : |
| 72 public base::RefCounted<WebRtcAudioCapturer::ConfiguredBuffer> { | 55 public base::RefCounted<WebRtcAudioCapturer::ConfiguredBuffer> { |
| 73 public: | 56 public: |
| 74 ConfiguredBuffer() {} | 57 ConfiguredBuffer() {} |
| 75 | 58 |
| 76 bool Initialize(int sample_rate, | 59 bool Initialize(int sample_rate, |
| 77 media::ChannelLayout channel_layout) { | 60 media::ChannelLayout channel_layout) { |
| 78 int buffer_size = GetBufferSizeForSampleRate(sample_rate); | 61 int buffer_size = GetBufferSizeForSampleRate(sample_rate); |
| 79 if (!buffer_size) { | 62 DVLOG(1) << "Using WebRTC input buffer size: " << buffer_size; |
| 80 DLOG(ERROR) << "Unsupported sample-rate: " << sample_rate; | |
| 81 return false; | |
| 82 } | |
| 83 | 63 |
| 84 media::AudioParameters::Format format = | 64 media::AudioParameters::Format format = |
| 85 media::AudioParameters::AUDIO_PCM_LOW_LATENCY; | 65 media::AudioParameters::AUDIO_PCM_LOW_LATENCY; |
| 86 | 66 |
| 87 // bits_per_sample is always 16 for now. | 67 // bits_per_sample is always 16 for now. |
| 88 int bits_per_sample = 16; | 68 int bits_per_sample = 16; |
| 89 int channels = ChannelLayoutToChannelCount(channel_layout); | 69 int channels = ChannelLayoutToChannelCount(channel_layout); |
| 90 params_.Reset(format, channel_layout, channels, 0, | 70 params_.Reset(format, channel_layout, channels, 0, |
| 91 sample_rate, bits_per_sample, buffer_size); | 71 sample_rate, bits_per_sample, buffer_size); |
| 92 buffer_.reset(new int16[params_.frames_per_buffer() * params_.channels()]); | 72 buffer_.reset(new int16[params_.frames_per_buffer() * params_.channels()]); |
| (...skipping 294 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 } | 367 } |
| 388 | 368 |
| 389 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { | 369 media::AudioParameters WebRtcAudioCapturer::audio_parameters() const { |
| 390 base::AutoLock auto_lock(lock_); | 370 base::AutoLock auto_lock(lock_); |
| 391 // |buffer_| can be NULL when SetCapturerSource() or Initialize() has not | 371 // |buffer_| can be NULL when SetCapturerSource() or Initialize() has not |
| 392 // been called. | 372 // been called. |
| 393 return buffer_.get() ? buffer_->params() : media::AudioParameters(); | 373 return buffer_.get() ? buffer_->params() : media::AudioParameters(); |
| 394 } | 374 } |
| 395 | 375 |
| 396 } // namespace content | 376 } // namespace content |
| OLD | NEW |