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

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

Issue 37793005: move the APM to chrome. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 2 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_local_audio_track.h" 5 #include "content/renderer/media/webrtc_local_audio_track.h"
6 6
7 #include "content/renderer/media/webaudio_capturer_source.h" 7 #include "content/renderer/media/webaudio_capturer_source.h"
8 #include "content/renderer/media/webrtc_audio_capturer.h" 8 #include "content/renderer/media/webrtc_audio_capturer.h"
9 #include "content/renderer/media/webrtc_audio_capturer_sink_owner.h" 9 #include "content/renderer/media/webrtc_audio_capturer_sink_owner.h"
10 #include "content/renderer/media/webrtc_local_audio_source_provider.h" 10 #include "content/renderer/media/webrtc_local_audio_source_provider.h"
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 value) { 45 value) {
46 return true; 46 return true;
47 } 47 }
48 } 48 }
49 49
50 return false; 50 return false;
51 } 51 }
52 52
53 } // namespace. 53 } // namespace.
54 54
55 // This is a temporary audio buffer with parameters used to send data to
56 // callbacks.
57 class WebRtcLocalAudioTrack::ConfiguredBuffer :
58 public base::RefCounted<WebRtcLocalAudioTrack::ConfiguredBuffer> {
59 public:
60 ConfiguredBuffer() : sink_buffer_size_(0) {}
61
62 void Initialize(const media::AudioParameters& params) {
63 DCHECK(params.IsValid());
64 params_ = params;
65
66 // Use 10ms as the sink buffer size since that is the native packet size
67 // WebRtc is running on.
68 sink_buffer_size_ = params.sample_rate() / 100;
69 audio_wrapper_ =
70 media::AudioBus::Create(params.channels(), sink_buffer_size_);
71 buffer_.reset(new int16[sink_buffer_size_ * params.channels()]);
72
73 // The size of the FIFO should be at least twice of the source buffer size
74 // or twice of the sink buffer size.
75 int buffer_size = std::max(
76 kMaxNumberOfBuffersInFifo * params.frames_per_buffer(),
77 kMaxNumberOfBuffersInFifo * sink_buffer_size_);
78 fifo_.reset(new media::AudioFifo(params.channels(), buffer_size));
79 }
80
81 void Push(media::AudioBus* audio_source) {
82 DCHECK(fifo_->frames() + audio_source->frames() <= fifo_->max_frames());
83 fifo_->Push(audio_source);
84 }
85
86 bool Consume() {
87 if (fifo_->frames() < audio_wrapper_->frames())
88 return false;
89
90 fifo_->Consume(audio_wrapper_.get(), 0, audio_wrapper_->frames());
91 audio_wrapper_->ToInterleaved(audio_wrapper_->frames(),
92 params_.bits_per_sample() / 8,
93 buffer());
94 return true;
95 }
96
97 int16* buffer() const { return buffer_.get(); }
98 const media::AudioParameters& params() const { return params_; }
99 int sink_buffer_size() const { return sink_buffer_size_; }
100
101 private:
102 ~ConfiguredBuffer() {}
103 friend class base::RefCounted<WebRtcLocalAudioTrack::ConfiguredBuffer>;
104
105 media::AudioParameters params_;
106 scoped_ptr<media::AudioBus> audio_wrapper_;
107 scoped_ptr<media::AudioFifo> fifo_;
108 scoped_ptr<int16[]> buffer_;
109 int sink_buffer_size_;
110 };
111
112 scoped_refptr<WebRtcLocalAudioTrack> WebRtcLocalAudioTrack::Create( 55 scoped_refptr<WebRtcLocalAudioTrack> WebRtcLocalAudioTrack::Create(
113 const std::string& id, 56 const std::string& id,
114 const scoped_refptr<WebRtcAudioCapturer>& capturer, 57 const scoped_refptr<WebRtcAudioCapturer>& capturer,
115 WebAudioCapturerSource* webaudio_source, 58 WebAudioCapturerSource* webaudio_source,
116 webrtc::AudioSourceInterface* track_source, 59 webrtc::AudioSourceInterface* track_source,
117 const webrtc::MediaConstraintsInterface* constraints) { 60 const webrtc::MediaConstraintsInterface* constraints) {
118 talk_base::RefCountedObject<WebRtcLocalAudioTrack>* track = 61 talk_base::RefCountedObject<WebRtcLocalAudioTrack>* track =
119 new talk_base::RefCountedObject<WebRtcLocalAudioTrack>( 62 new talk_base::RefCountedObject<WebRtcLocalAudioTrack>(
120 id, capturer, webaudio_source, track_source, constraints); 63 id, capturer, webaudio_source, track_source, constraints);
121 return track; 64 return track;
(...skipping 14 matching lines...) Expand all
136 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()"; 79 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()";
137 } 80 }
138 81
139 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { 82 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() {
140 DCHECK(thread_checker_.CalledOnValidThread()); 83 DCHECK(thread_checker_.CalledOnValidThread());
141 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; 84 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()";
142 // Users might not call Stop() on the track. 85 // Users might not call Stop() on the track.
143 Stop(); 86 Stop();
144 } 87 }
145 88
146 void WebRtcLocalAudioTrack::Capture(media::AudioBus* audio_source, 89 void WebRtcLocalAudioTrack::Capture(const int16* audio_data,
147 int audio_delay_milliseconds, 90 int sample_rate,
148 int volume, 91 int number_of_channels,
149 bool key_pressed) { 92 int number_of_frames) {
150 scoped_refptr<WebRtcAudioCapturer> capturer; 93 DCHECK(number_of_frames == (sample_rate / 100));
94
151 std::vector<int> voe_channels; 95 std::vector<int> voe_channels;
152 int sample_rate = 0;
153 int number_of_channels = 0;
154 int number_of_frames = 0;
155 SinkList sinks; 96 SinkList sinks;
156 bool is_webaudio_source = false;
157 scoped_refptr<ConfiguredBuffer> current_buffer;
158 { 97 {
159 base::AutoLock auto_lock(lock_); 98 base::AutoLock auto_lock(lock_);
160 capturer = capturer_;
161 voe_channels = voe_channels_; 99 voe_channels = voe_channels_;
162 current_buffer = buffer_;
163 sample_rate = current_buffer->params().sample_rate();
164 number_of_channels = current_buffer->params().channels();
165 number_of_frames = current_buffer->sink_buffer_size();
166 sinks = sinks_; 100 sinks = sinks_;
167 is_webaudio_source = (webaudio_source_.get() != NULL);
168 } 101 }
169 102
170 // Push the data to the fifo. 103 // Feed the data to the sinks.
171 current_buffer->Push(audio_source); 104 // TODO (jiayl): we should not pass the real audio data down if the track is
172 105 // disabled. This is currently done so to feed input to WebRTC typing
173 // When the source is WebAudio, turn off the audio processing if the delay 106 // detection and should be changed when audio processing is moved from
174 // value is 0 even though the constraint is set to true. In such case, it 107 // WebRTC to the track.
175 // indicates the data is not from microphone. 108 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) {
176 // TODO(xians): remove the flag when supporting one APM per audio track. 109 (*it)->CaptureData(voe_channels,
177 // See crbug/264611 for details. 110 audio_data,
178 bool need_audio_processing = need_audio_processing_; 111 sample_rate,
179 if (is_webaudio_source && need_audio_processing) 112 number_of_channels,
180 need_audio_processing = (audio_delay_milliseconds != 0); 113 number_of_frames);
181
182 int current_volume = volume;
183 while (current_buffer->Consume()) {
184 // Feed the data to the sinks.
185 // TODO (jiayl): we should not pass the real audio data down if the track is
186 // disabled. This is currently done so to feed input to WebRTC typing
187 // detection and should be changed when audio processing is moved from
188 // WebRTC to the track.
189 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) {
190 int new_volume = (*it)->CaptureData(voe_channels,
191 current_buffer->buffer(),
192 sample_rate,
193 number_of_channels,
194 number_of_frames,
195 audio_delay_milliseconds,
196 current_volume,
197 need_audio_processing,
198 key_pressed);
199 if (new_volume != 0 && capturer.get()) {
200 // Feed the new volume to WebRtc while changing the volume on the
201 // browser.
202 capturer->SetVolume(new_volume);
203 current_volume = new_volume;
204 }
205 }
206 } 114 }
207 } 115 }
208 116
209 void WebRtcLocalAudioTrack::SetCaptureFormat( 117 void WebRtcLocalAudioTrack::SetCaptureFormat(
210 const media::AudioParameters& params) { 118 const media::AudioParameters& params) {
211 if (!params.IsValid()) 119 if (!params.IsValid())
212 return; 120 return;
213 121
214 scoped_refptr<ConfiguredBuffer> new_buffer(new ConfiguredBuffer());
215 new_buffer->Initialize(params);
216
217 SinkList sinks; 122 SinkList sinks;
218 { 123 {
219 base::AutoLock auto_lock(lock_); 124 base::AutoLock auto_lock(lock_);
220 buffer_ = new_buffer; 125 params_ = params;
221 sinks = sinks_; 126 sinks = sinks_;
222 } 127 }
223 128
224 // Update all the existing sinks with the new format. 129 // Update all the existing sinks with the new format.
225 for (SinkList::const_iterator it = sinks.begin(); 130 for (SinkList::const_iterator it = sinks.begin();
226 it != sinks.end(); ++it) { 131 it != sinks.end(); ++it) {
227 (*it)->SetCaptureFormat(params); 132 (*it)->SetCaptureFormat(params);
228 } 133 }
229 } 134 }
230 135
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
262 } 167 }
263 168
264 std::string WebRtcLocalAudioTrack::kind() const { 169 std::string WebRtcLocalAudioTrack::kind() const {
265 return kAudioTrackKind; 170 return kAudioTrackKind;
266 } 171 }
267 172
268 void WebRtcLocalAudioTrack::AddSink(WebRtcAudioCapturerSink* sink) { 173 void WebRtcLocalAudioTrack::AddSink(WebRtcAudioCapturerSink* sink) {
269 DCHECK(thread_checker_.CalledOnValidThread()); 174 DCHECK(thread_checker_.CalledOnValidThread());
270 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()"; 175 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()";
271 base::AutoLock auto_lock(lock_); 176 base::AutoLock auto_lock(lock_);
272 if (buffer_.get()) 177
273 sink->SetCaptureFormat(buffer_->params()); 178 sink->SetCaptureFormat(params_);
274 179
275 // Verify that |sink| is not already added to the list. 180 // Verify that |sink| is not already added to the list.
276 DCHECK(std::find_if( 181 DCHECK(std::find_if(
277 sinks_.begin(), sinks_.end(), 182 sinks_.begin(), sinks_.end(),
278 WebRtcAudioCapturerSinkOwner::WrapsSink(sink)) == sinks_.end()); 183 WebRtcAudioCapturerSinkOwner::WrapsSink(sink)) == sinks_.end());
279 184
280 // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns 185 // Create (and add to the list) a new WebRtcAudioCapturerSinkOwner which owns
281 // the |sink| and delagates all calls to the WebRtcAudioCapturerSink 186 // the |sink| and delagates all calls to the WebRtcAudioCapturerSink
282 // interface. 187 // interface.
283 sinks_.push_back(new WebRtcAudioCapturerSinkOwner(sink)); 188 sinks_.push_back(new WebRtcAudioCapturerSinkOwner(sink));
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
346 sinks = sinks_; 251 sinks = sinks_;
347 webaudio_source_ = NULL; 252 webaudio_source_ = NULL;
348 capturer_ = NULL; 253 capturer_ = NULL;
349 } 254 }
350 255
351 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it) 256 for (SinkList::const_iterator it = sinks.begin(); it != sinks.end(); ++it)
352 (*it)->Reset(); 257 (*it)->Reset();
353 } 258 }
354 259
355 } // namespace content 260 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698