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 |