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/macros.h" | 9 #include "base/macros.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/strings/string_util.h" | 11 #include "base/strings/string_util.h" |
12 #include "base/strings/stringprintf.h" | 12 #include "base/strings/stringprintf.h" |
13 #include "build/build_config.h" | 13 #include "build/build_config.h" |
14 #include "content/child/child_process.h" | 14 #include "content/child/child_process.h" |
15 #include "content/renderer/media/audio_device_factory.h" | 15 #include "content/renderer/media/audio_device_factory.h" |
16 #include "content/renderer/media/media_stream_audio_processor.h" | 16 #include "content/renderer/media/media_stream_audio_processor.h" |
17 #include "content/renderer/media/media_stream_audio_processor_options.h" | 17 #include "content/renderer/media/media_stream_audio_processor_options.h" |
18 #include "content/renderer/media/media_stream_audio_source.h" | 18 #include "content/renderer/media/media_stream_audio_source.h" |
19 #include "content/renderer/media/media_stream_constraints_util.h" | 19 #include "content/renderer/media/media_stream_constraints_util.h" |
20 #include "content/renderer/media/webrtc_audio_device_impl.h" | 20 #include "content/renderer/media/webrtc_audio_device_impl.h" |
21 #include "content/renderer/media/webrtc_local_audio_track.h" | 21 #include "content/renderer/media/webrtc_local_audio_track.h" |
22 #include "content/renderer/media/webrtc_logging.h" | 22 #include "content/renderer/media/webrtc_logging.h" |
23 #include "media/audio/sample_rates.h" | 23 #include "media/audio/sample_rates.h" |
24 | 24 |
25 namespace content { | 25 namespace content { |
26 | 26 |
27 namespace { | |
28 | |
29 // Audio buffer sizes are specified in milliseconds. | |
30 const char kAudioLatency[] = "latencyMs"; | |
31 const int kMinAudioLatencyMs = 0; | |
32 const int kMaxAudioLatencyMs = 10000; | |
33 | |
34 // Method to check if any of the data in |audio_source| has energy. | |
35 bool HasDataEnergy(const media::AudioBus& audio_source) { | |
36 for (int ch = 0; ch < audio_source.channels(); ++ch) { | |
37 const float* channel_ptr = audio_source.channel(ch); | |
38 for (int frame = 0; frame < audio_source.frames(); ++frame) { | |
39 if (channel_ptr[frame] != 0) | |
40 return true; | |
41 } | |
42 } | |
43 | |
44 // All the data is zero. | |
45 return false; | |
46 } | |
47 | |
48 } // namespace | |
49 | |
50 // Reference counted container of WebRtcLocalAudioTrack delegate. | 27 // Reference counted container of WebRtcLocalAudioTrack delegate. |
51 // TODO(xians): Switch to MediaStreamAudioSinkOwner. | 28 // TODO(xians): Switch to MediaStreamAudioSinkOwner. |
52 class WebRtcAudioCapturer::TrackOwner | 29 class WebRtcAudioCapturer::TrackOwner |
53 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> { | 30 : public base::RefCountedThreadSafe<WebRtcAudioCapturer::TrackOwner> { |
54 public: | 31 public: |
55 explicit TrackOwner(WebRtcLocalAudioTrack* track) | 32 explicit TrackOwner(WebRtcLocalAudioTrack* track) |
56 : delegate_(track) {} | 33 : delegate_(track) {} |
57 | 34 |
58 void Capture(const media::AudioBus& audio_bus, | 35 void Capture(const media::AudioBus& audio_bus, |
59 base::TimeTicks estimated_capture_time, | 36 base::TimeTicks estimated_capture_time) { |
60 bool force_report_nonzero_energy) { | |
61 base::AutoLock lock(lock_); | 37 base::AutoLock lock(lock_); |
62 if (delegate_) { | 38 if (delegate_) { |
63 delegate_->Capture(audio_bus, | 39 delegate_->Capture(audio_bus, estimated_capture_time); |
64 estimated_capture_time, | |
65 force_report_nonzero_energy); | |
66 } | 40 } |
67 } | 41 } |
68 | 42 |
69 void OnSetFormat(const media::AudioParameters& params) { | 43 void OnSetFormat(const media::AudioParameters& params) { |
70 base::AutoLock lock(lock_); | 44 base::AutoLock lock(lock_); |
71 if (delegate_) | 45 if (delegate_) |
72 delegate_->OnSetFormat(params); | 46 delegate_->OnSetFormat(params); |
73 } | 47 } |
74 | 48 |
75 void SetAudioProcessor( | |
76 const scoped_refptr<MediaStreamAudioProcessor>& processor) { | |
77 base::AutoLock lock(lock_); | |
78 if (delegate_) | |
79 delegate_->SetAudioProcessor(processor); | |
80 } | |
81 | |
82 void Reset() { | 49 void Reset() { |
83 base::AutoLock lock(lock_); | 50 base::AutoLock lock(lock_); |
84 delegate_ = NULL; | 51 delegate_ = NULL; |
85 } | 52 } |
86 | 53 |
87 void Stop() { | 54 void Stop() { |
88 base::AutoLock lock(lock_); | 55 base::AutoLock lock(lock_); |
89 DCHECK(delegate_); | 56 DCHECK(delegate_); |
90 | 57 |
91 // This can be reentrant so reset |delegate_| before calling out. | 58 // This can be reentrant so reset |delegate_| before calling out. |
(...skipping 25 matching lines...) Expand all Loading... |
117 } | 84 } |
118 | 85 |
119 // Do NOT reference count the |delegate_| to avoid cyclic reference counting. | 86 // Do NOT reference count the |delegate_| to avoid cyclic reference counting. |
120 WebRtcLocalAudioTrack* delegate_; | 87 WebRtcLocalAudioTrack* delegate_; |
121 mutable base::Lock lock_; | 88 mutable base::Lock lock_; |
122 | 89 |
123 DISALLOW_COPY_AND_ASSIGN(TrackOwner); | 90 DISALLOW_COPY_AND_ASSIGN(TrackOwner); |
124 }; | 91 }; |
125 | 92 |
126 // static | 93 // static |
127 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer( | 94 scoped_ptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer( |
128 int render_frame_id, | 95 int render_frame_id, |
129 const StreamDeviceInfo& device_info, | 96 const StreamDeviceInfo& device_info, |
130 const blink::WebMediaConstraints& constraints, | 97 const blink::WebMediaConstraints& constraints, |
131 WebRtcAudioDeviceImpl* audio_device, | 98 WebRtcAudioDeviceImpl* audio_device, |
132 MediaStreamAudioSource* audio_source) { | 99 MediaStreamAudioSource* audio_source) { |
133 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer( | 100 scoped_ptr<WebRtcAudioCapturer> capturer(new WebRtcAudioCapturer( |
134 render_frame_id, device_info, constraints, audio_device, audio_source); | 101 render_frame_id, device_info, constraints, audio_device, audio_source)); |
135 if (capturer->Initialize()) | 102 if (capturer->Initialize()) |
136 return capturer; | 103 return capturer; |
137 | 104 |
138 return NULL; | 105 return NULL; |
139 } | 106 } |
140 | 107 |
141 bool WebRtcAudioCapturer::Initialize() { | 108 bool WebRtcAudioCapturer::Initialize() { |
142 DCHECK(thread_checker_.CalledOnValidThread()); | 109 DCHECK(thread_checker_.CalledOnValidThread()); |
143 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; | 110 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; |
144 WebRtcLogMessage(base::StringPrintf( | 111 WebRtcLogMessage(base::StringPrintf( |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
199 << device_info_.device.input.sample_rate; | 166 << device_info_.device.input.sample_rate; |
200 media::AudioSampleRate asr; | 167 media::AudioSampleRate asr; |
201 if (media::ToAudioSampleRate(device_info_.device.input.sample_rate, &asr)) { | 168 if (media::ToAudioSampleRate(device_info_.device.input.sample_rate, &asr)) { |
202 UMA_HISTOGRAM_ENUMERATION( | 169 UMA_HISTOGRAM_ENUMERATION( |
203 "WebRTC.AudioInputSampleRate", asr, media::kAudioSampleRateMax + 1); | 170 "WebRTC.AudioInputSampleRate", asr, media::kAudioSampleRateMax + 1); |
204 } else { | 171 } else { |
205 UMA_HISTOGRAM_COUNTS("WebRTC.AudioInputSampleRateUnexpected", | 172 UMA_HISTOGRAM_COUNTS("WebRTC.AudioInputSampleRateUnexpected", |
206 device_info_.device.input.sample_rate); | 173 device_info_.device.input.sample_rate); |
207 } | 174 } |
208 | 175 |
209 // Initialize the buffer size to zero, which means it wasn't specified. | |
210 // If it is out of range, we return it to zero. | |
211 int buffer_size_ms = 0; | |
212 int buffer_size_samples = 0; | |
213 GetConstraintValueAsInteger(constraints_, kAudioLatency, &buffer_size_ms); | |
214 if (buffer_size_ms < kMinAudioLatencyMs || | |
215 buffer_size_ms > kMaxAudioLatencyMs) { | |
216 DVLOG(1) << "Ignoring out of range buffer size " << buffer_size_ms; | |
217 } else { | |
218 buffer_size_samples = | |
219 device_info_.device.input.sample_rate * buffer_size_ms / 1000; | |
220 } | |
221 DVLOG_IF(1, buffer_size_samples > 0) | |
222 << "Custom audio buffer size: " << buffer_size_samples << " samples"; | |
223 | |
224 // Create and configure the default audio capturing source. | 176 // Create and configure the default audio capturing source. |
225 SetCapturerSourceInternal( | 177 SetCapturerSourceInternal( |
226 AudioDeviceFactory::NewInputDevice(render_frame_id_), | 178 AudioDeviceFactory::NewInputDevice(render_frame_id_), channel_layout, |
227 channel_layout, | 179 device_info_.device.input.sample_rate); |
228 device_info_.device.input.sample_rate, | |
229 buffer_size_samples); | |
230 | 180 |
231 // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware | 181 // Add the capturer to the WebRtcAudioDeviceImpl since it needs some hardware |
232 // information from the capturer. | 182 // information from the capturer. |
233 if (audio_device_) | 183 if (audio_device_) |
234 audio_device_->AddAudioCapturer(this); | 184 audio_device_->AddAudioCapturer(this); |
235 | 185 |
236 return true; | 186 return true; |
237 } | 187 } |
238 | 188 |
239 WebRtcAudioCapturer::WebRtcAudioCapturer( | 189 WebRtcAudioCapturer::WebRtcAudioCapturer( |
240 int render_frame_id, | 190 int render_frame_id, |
241 const StreamDeviceInfo& device_info, | 191 const StreamDeviceInfo& device_info, |
242 const blink::WebMediaConstraints& constraints, | 192 const blink::WebMediaConstraints& constraints, |
243 WebRtcAudioDeviceImpl* audio_device, | 193 WebRtcAudioDeviceImpl* audio_device, |
244 MediaStreamAudioSource* audio_source) | 194 MediaStreamAudioSource* audio_source) |
245 : constraints_(constraints), | 195 : constraints_(constraints), |
246 audio_processor_(new rtc::RefCountedObject<MediaStreamAudioProcessor>( | 196 audio_processor_(new rtc::RefCountedObject<MediaStreamAudioProcessor>( |
247 constraints, | 197 constraints, |
248 device_info.device.input, | 198 device_info.device.input, |
249 audio_device)), | 199 audio_device)), |
250 running_(false), | 200 running_(false), |
251 render_frame_id_(render_frame_id), | 201 render_frame_id_(render_frame_id), |
252 device_info_(device_info), | 202 device_info_(device_info), |
253 volume_(0), | 203 volume_(0), |
254 peer_connection_mode_(false), | 204 peer_connection_mode_(false), |
255 audio_device_(audio_device), | 205 audio_device_(audio_device), |
256 audio_source_(audio_source) { | 206 audio_source_(audio_source), |
| 207 weak_factory_(this) { |
257 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; | 208 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; |
258 } | 209 } |
259 | 210 |
260 WebRtcAudioCapturer::~WebRtcAudioCapturer() { | 211 WebRtcAudioCapturer::~WebRtcAudioCapturer() { |
261 DCHECK(thread_checker_.CalledOnValidThread()); | 212 DCHECK(thread_checker_.CalledOnValidThread()); |
262 DCHECK(tracks_.IsEmpty()); | 213 DCHECK(tracks_.IsEmpty()); |
263 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; | 214 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; |
264 Stop(); | 215 Stop(); |
265 } | 216 } |
266 | 217 |
267 void WebRtcAudioCapturer::AddTrack(WebRtcLocalAudioTrack* track) { | 218 void WebRtcAudioCapturer::AddTrack(WebRtcLocalAudioTrack* track) { |
| 219 DCHECK(thread_checker_.CalledOnValidThread()); |
268 DCHECK(track); | 220 DCHECK(track); |
269 DVLOG(1) << "WebRtcAudioCapturer::AddTrack()"; | 221 DVLOG(1) << "WebRtcAudioCapturer::AddTrack()"; |
270 | 222 |
| 223 track->AddStopObserver(base::Bind(&WebRtcAudioCapturer::RemoveTrack, |
| 224 weak_factory_.GetWeakPtr(), track)); |
| 225 track->SetLevel(level_calculator_.level()); |
| 226 |
| 227 // The track only grabs stats from the audio processor. Stats are only |
| 228 // available if audio processing is turned on. Therefore, only provide the |
| 229 // track a reference if audio processing is turned on. |
| 230 if (audio_processor_->has_audio_processing()) |
| 231 track->SetAudioProcessor(audio_processor_); |
| 232 |
271 { | 233 { |
272 base::AutoLock auto_lock(lock_); | 234 base::AutoLock auto_lock(lock_); |
273 // Verify that |track| is not already added to the list. | 235 // Verify that |track| is not already added to the list. |
274 DCHECK(!tracks_.Contains(TrackOwner::TrackWrapper(track))); | 236 DCHECK(!tracks_.Contains(TrackOwner::TrackWrapper(track))); |
275 | 237 |
276 // Add with a tag, so we remember to call OnSetFormat() on the new | 238 // Add with a tag, so we remember to call OnSetFormat() on the new |
277 // track. | 239 // track. |
278 scoped_refptr<TrackOwner> track_owner(new TrackOwner(track)); | 240 scoped_refptr<TrackOwner> track_owner(new TrackOwner(track)); |
279 tracks_.AddAndTag(track_owner.get()); | 241 tracks_.AddAndTag(track_owner.get()); |
280 } | 242 } |
(...skipping 23 matching lines...) Expand all Loading... |
304 // we have to call StopSource on the MediaStreamSource. This will call | 266 // we have to call StopSource on the MediaStreamSource. This will call |
305 // MediaStreamAudioSource::DoStopSource which in turn call | 267 // MediaStreamAudioSource::DoStopSource which in turn call |
306 // WebRtcAudioCapturerer::Stop(); | 268 // WebRtcAudioCapturerer::Stop(); |
307 audio_source_->StopSource(); | 269 audio_source_->StopSource(); |
308 } | 270 } |
309 } | 271 } |
310 | 272 |
311 void WebRtcAudioCapturer::SetCapturerSourceInternal( | 273 void WebRtcAudioCapturer::SetCapturerSourceInternal( |
312 const scoped_refptr<media::AudioCapturerSource>& source, | 274 const scoped_refptr<media::AudioCapturerSource>& source, |
313 media::ChannelLayout channel_layout, | 275 media::ChannelLayout channel_layout, |
314 int sample_rate, | 276 int sample_rate) { |
315 int buffer_size) { | |
316 DCHECK(thread_checker_.CalledOnValidThread()); | 277 DCHECK(thread_checker_.CalledOnValidThread()); |
317 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," | 278 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," |
318 << "sample_rate=" << sample_rate << ")"; | 279 << "sample_rate=" << sample_rate << ")"; |
319 scoped_refptr<media::AudioCapturerSource> old_source; | 280 scoped_refptr<media::AudioCapturerSource> old_source; |
320 { | 281 { |
321 base::AutoLock auto_lock(lock_); | 282 base::AutoLock auto_lock(lock_); |
322 if (source_.get() == source.get()) | 283 if (source_.get() == source.get()) |
323 return; | 284 return; |
324 | 285 |
325 source_.swap(old_source); | 286 source_.swap(old_source); |
326 source_ = source; | 287 source_ = source; |
327 | 288 |
328 // Reset the flag to allow starting the new source. | 289 // Reset the flag to allow starting the new source. |
329 running_ = false; | 290 running_ = false; |
330 } | 291 } |
331 | 292 |
332 DVLOG(1) << "Switching to a new capture source."; | 293 DVLOG(1) << "Switching to a new capture source."; |
333 if (old_source.get()) | 294 if (old_source.get()) |
334 old_source->Stop(); | 295 old_source->Stop(); |
335 | 296 |
336 // If the buffer size is zero, it has not been specified. | |
337 // We either default to 10ms, or use the hardware buffer size. | |
338 if (buffer_size == 0) | |
339 buffer_size = GetBufferSize(sample_rate); | |
340 | |
341 // Dispatch the new parameters both to the sink(s) and to the new source, | 297 // Dispatch the new parameters both to the sink(s) and to the new source, |
342 // also apply the new |constraints|. | 298 // also apply the new |constraints|. |
343 // The idea is to get rid of any dependency of the microphone parameters | 299 // The idea is to get rid of any dependency of the microphone parameters |
344 // which would normally be used by default. | 300 // which would normally be used by default. |
345 // bits_per_sample is always 16 for now. | 301 // bits_per_sample is always 16 for now. |
346 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, | 302 media::AudioParameters params(media::AudioParameters::AUDIO_PCM_LOW_LATENCY, |
347 channel_layout, sample_rate, 16, buffer_size); | 303 channel_layout, sample_rate, 16, |
| 304 GetBufferSize(sample_rate)); |
348 params.set_effects(device_info_.device.input.effects); | 305 params.set_effects(device_info_.device.input.effects); |
| 306 DCHECK(params.IsValid()); |
349 | 307 |
350 { | 308 { |
351 base::AutoLock auto_lock(lock_); | 309 base::AutoLock auto_lock(lock_); |
352 // Notify the |audio_processor_| of the new format. | 310 // Notify the |audio_processor_| of the new format. |
353 audio_processor_->OnCaptureFormatChanged(params); | 311 audio_processor_->OnCaptureFormatChanged(params); |
354 | 312 |
355 // Notify all tracks about the new format. | 313 // Notify all tracks about the new format. |
356 tracks_.TagAll(); | 314 tracks_.TagAll(); |
357 } | 315 } |
358 | 316 |
359 if (source.get()) | 317 if (source.get()) |
360 source->Initialize(params, this, session_id()); | 318 source->Initialize(params, this, device_info_.session_id); |
361 | 319 |
362 Start(); | 320 Start(); |
363 } | 321 } |
364 | 322 |
365 void WebRtcAudioCapturer::EnablePeerConnectionMode() { | 323 void WebRtcAudioCapturer::EnablePeerConnectionMode() { |
366 DCHECK(thread_checker_.CalledOnValidThread()); | 324 DCHECK(thread_checker_.CalledOnValidThread()); |
367 DVLOG(1) << "EnablePeerConnectionMode"; | 325 DVLOG(1) << "EnablePeerConnectionMode"; |
368 // Do nothing if the peer connection mode has been enabled. | 326 // Do nothing if the peer connection mode has been enabled. |
369 if (peer_connection_mode_) | 327 if (peer_connection_mode_) |
370 return; | 328 return; |
(...skipping 15 matching lines...) Expand all Loading... |
386 // Do nothing if the current buffer size is the WebRtc native buffer size. | 344 // Do nothing if the current buffer size is the WebRtc native buffer size. |
387 if (GetBufferSize(input_params.sample_rate()) == | 345 if (GetBufferSize(input_params.sample_rate()) == |
388 input_params.frames_per_buffer()) { | 346 input_params.frames_per_buffer()) { |
389 return; | 347 return; |
390 } | 348 } |
391 | 349 |
392 // Create a new audio stream as source which will open the hardware using | 350 // Create a new audio stream as source which will open the hardware using |
393 // WebRtc native buffer size. | 351 // WebRtc native buffer size. |
394 SetCapturerSourceInternal(AudioDeviceFactory::NewInputDevice(render_frame_id), | 352 SetCapturerSourceInternal(AudioDeviceFactory::NewInputDevice(render_frame_id), |
395 input_params.channel_layout(), | 353 input_params.channel_layout(), |
396 input_params.sample_rate(), | 354 input_params.sample_rate()); |
397 0); | |
398 } | 355 } |
399 | 356 |
400 void WebRtcAudioCapturer::Start() { | 357 void WebRtcAudioCapturer::Start() { |
401 DCHECK(thread_checker_.CalledOnValidThread()); | 358 DCHECK(thread_checker_.CalledOnValidThread()); |
402 DVLOG(1) << "WebRtcAudioCapturer::Start()"; | 359 DVLOG(1) << "WebRtcAudioCapturer::Start()"; |
403 base::AutoLock auto_lock(lock_); | 360 base::AutoLock auto_lock(lock_); |
404 if (running_ || !source_.get()) | 361 if (running_ || !source_.get()) |
405 return; | 362 return; |
406 | 363 |
407 // Start the data source, i.e., start capturing data from the current source. | 364 // Start the data source, i.e., start capturing data from the current source. |
(...skipping 16 matching lines...) Expand all Loading... |
424 source = source_; | 381 source = source_; |
425 tracks = tracks_.Items(); | 382 tracks = tracks_.Items(); |
426 tracks_.Clear(); | 383 tracks_.Clear(); |
427 running_ = false; | 384 running_ = false; |
428 } | 385 } |
429 | 386 |
430 // Remove the capturer object from the WebRtcAudioDeviceImpl. | 387 // Remove the capturer object from the WebRtcAudioDeviceImpl. |
431 if (audio_device_) | 388 if (audio_device_) |
432 audio_device_->RemoveAudioCapturer(this); | 389 audio_device_->RemoveAudioCapturer(this); |
433 | 390 |
| 391 // Invalidate the weak pointers since we don't need the tracks to call our |
| 392 // RemoveTrack() method when their Stop() method is called. |
| 393 weak_factory_.InvalidateWeakPtrs(); |
| 394 |
434 for (TrackList::ItemList::const_iterator it = tracks.begin(); | 395 for (TrackList::ItemList::const_iterator it = tracks.begin(); |
435 it != tracks.end(); | 396 it != tracks.end(); |
436 ++it) { | 397 ++it) { |
437 (*it)->Stop(); | 398 (*it)->Stop(); |
438 } | 399 } |
439 | 400 |
440 if (source.get()) | 401 if (source.get()) |
441 source->Stop(); | 402 source->Stop(); |
442 | 403 |
443 // Stop the audio processor to avoid feeding render data into the processor. | 404 // Stop the audio processor to avoid feeding render data into the processor. |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
510 DCHECK(audio_processor_->InputFormat().IsValid()); | 471 DCHECK(audio_processor_->InputFormat().IsValid()); |
511 DCHECK_EQ(audio_source->channels(), | 472 DCHECK_EQ(audio_source->channels(), |
512 audio_processor_->InputFormat().channels()); | 473 audio_processor_->InputFormat().channels()); |
513 DCHECK_EQ(audio_source->frames(), | 474 DCHECK_EQ(audio_source->frames(), |
514 audio_processor_->InputFormat().frames_per_buffer()); | 475 audio_processor_->InputFormat().frames_per_buffer()); |
515 | 476 |
516 // Notify the tracks on when the format changes. This will do nothing if | 477 // Notify the tracks on when the format changes. This will do nothing if |
517 // |tracks_to_notify_format| is empty. | 478 // |tracks_to_notify_format| is empty. |
518 const media::AudioParameters& output_params = | 479 const media::AudioParameters& output_params = |
519 audio_processor_->OutputFormat(); | 480 audio_processor_->OutputFormat(); |
520 for (const auto& track : tracks_to_notify_format) { | 481 for (const auto& track : tracks_to_notify_format) |
521 track->OnSetFormat(output_params); | 482 track->OnSetFormat(output_params); |
522 track->SetAudioProcessor(audio_processor_); | |
523 } | |
524 | 483 |
525 // Figure out if the pre-processed data has any energy or not, the | 484 // Figure out if the pre-processed data has any energy or not. This |
526 // information will be passed to the track to force the calculator | 485 // information will be passed to the level calculator to force it to report |
527 // to report energy in case the post-processed data is zeroed by the audio | 486 // energy in case the post-processed data is zeroed by the audio processing. |
528 // processing. | 487 const bool force_report_nonzero_energy = !audio_source->AreFramesZero(); |
529 const bool force_report_nonzero_energy = HasDataEnergy(*audio_source); | |
530 | 488 |
531 // Push the data to the processor for processing. | 489 // Push the data to the processor for processing. |
532 audio_processor_->PushCaptureData( | 490 audio_processor_->PushCaptureData( |
533 *audio_source, | 491 *audio_source, |
534 base::TimeDelta::FromMilliseconds(audio_delay_milliseconds)); | 492 base::TimeDelta::FromMilliseconds(audio_delay_milliseconds)); |
535 | 493 |
536 // Process and consume the data in the processor until there is not enough | 494 // Process and consume the data in the processor until there is not enough |
537 // data in the processor. | 495 // data in the processor. |
538 media::AudioBus* processed_data = nullptr; | 496 media::AudioBus* processed_data = nullptr; |
539 base::TimeDelta processed_data_audio_delay; | 497 base::TimeDelta processed_data_audio_delay; |
540 int new_volume = 0; | 498 int new_volume = 0; |
541 while (audio_processor_->ProcessAndConsumeData( | 499 while (audio_processor_->ProcessAndConsumeData( |
542 current_volume, key_pressed, | 500 current_volume, key_pressed, |
543 &processed_data, &processed_data_audio_delay, &new_volume)) { | 501 &processed_data, &processed_data_audio_delay, &new_volume)) { |
544 DCHECK(processed_data); | 502 DCHECK(processed_data); |
| 503 |
| 504 level_calculator_.Calculate(*processed_data, force_report_nonzero_energy); |
| 505 |
545 const base::TimeTicks processed_data_capture_time = | 506 const base::TimeTicks processed_data_capture_time = |
546 reference_clock_snapshot - processed_data_audio_delay; | 507 reference_clock_snapshot - processed_data_audio_delay; |
547 for (const auto& track : tracks) { | 508 for (const auto& track : tracks) |
548 track->Capture(*processed_data, | 509 track->Capture(*processed_data, processed_data_capture_time); |
549 processed_data_capture_time, | |
550 force_report_nonzero_energy); | |
551 } | |
552 | 510 |
553 if (new_volume) { | 511 if (new_volume) { |
554 SetVolume(new_volume); | 512 SetVolume(new_volume); |
555 | 513 |
556 // Update the |current_volume| to avoid passing the old volume to AGC. | 514 // Update the |current_volume| to avoid passing the old volume to AGC. |
557 current_volume = new_volume; | 515 current_volume = new_volume; |
558 } | 516 } |
559 } | 517 } |
560 } | 518 } |
561 | 519 |
562 void WebRtcAudioCapturer::OnCaptureError(const std::string& message) { | 520 void WebRtcAudioCapturer::OnCaptureError(const std::string& message) { |
563 WebRtcLogMessage("WAC::OnCaptureError: " + message); | 521 WebRtcLogMessage("WAC::OnCaptureError: " + message); |
564 } | 522 } |
565 | 523 |
566 media::AudioParameters WebRtcAudioCapturer::source_audio_parameters() const { | 524 media::AudioParameters WebRtcAudioCapturer::GetInputFormat() const { |
567 base::AutoLock auto_lock(lock_); | 525 base::AutoLock auto_lock(lock_); |
568 return audio_processor_.get() ? audio_processor_->InputFormat() | 526 return audio_processor_->InputFormat(); |
569 : media::AudioParameters(); | |
570 } | |
571 | |
572 bool WebRtcAudioCapturer::GetPairedOutputParameters( | |
573 int* session_id, | |
574 int* output_sample_rate, | |
575 int* output_frames_per_buffer) const { | |
576 // Don't set output parameters unless all of them are valid. | |
577 if (device_info_.session_id <= 0 || | |
578 !device_info_.device.matched_output.sample_rate || | |
579 !device_info_.device.matched_output.frames_per_buffer) | |
580 return false; | |
581 | |
582 *session_id = device_info_.session_id; | |
583 *output_sample_rate = device_info_.device.matched_output.sample_rate; | |
584 *output_frames_per_buffer = | |
585 device_info_.device.matched_output.frames_per_buffer; | |
586 | |
587 return true; | |
588 } | 527 } |
589 | 528 |
590 int WebRtcAudioCapturer::GetBufferSize(int sample_rate) const { | 529 int WebRtcAudioCapturer::GetBufferSize(int sample_rate) const { |
591 DCHECK(thread_checker_.CalledOnValidThread()); | 530 DCHECK(thread_checker_.CalledOnValidThread()); |
592 #if defined(OS_ANDROID) | 531 #if defined(OS_ANDROID) |
593 // TODO(henrika): Tune and adjust buffer size on Android. | 532 // TODO(henrika): Tune and adjust buffer size on Android. |
594 return (2 * sample_rate / 100); | 533 return (2 * sample_rate / 100); |
595 #endif | 534 #endif |
596 | 535 |
597 // PeerConnection is running at a buffer size of 10ms data. A multiple of | 536 // PeerConnection is running at a buffer size of 10ms data. A multiple of |
(...skipping 12 matching lines...) Expand all Loading... |
610 return hardware_buffer_size; | 549 return hardware_buffer_size; |
611 } | 550 } |
612 | 551 |
613 return (sample_rate / 100); | 552 return (sample_rate / 100); |
614 } | 553 } |
615 | 554 |
616 void WebRtcAudioCapturer::SetCapturerSource( | 555 void WebRtcAudioCapturer::SetCapturerSource( |
617 const scoped_refptr<media::AudioCapturerSource>& source, | 556 const scoped_refptr<media::AudioCapturerSource>& source, |
618 media::AudioParameters params) { | 557 media::AudioParameters params) { |
619 // Create a new audio stream as source which uses the new source. | 558 // Create a new audio stream as source which uses the new source. |
620 SetCapturerSourceInternal(source, | 559 SetCapturerSourceInternal(source, params.channel_layout(), |
621 params.channel_layout(), | 560 params.sample_rate()); |
622 params.sample_rate(), | |
623 0); | |
624 } | 561 } |
625 | 562 |
626 } // namespace content | 563 } // namespace content |
OLD | NEW |