Chromium Code Reviews| 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/strings/string_util.h" | 10 #include "base/strings/string_util.h" |
| 11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
| 12 #include "content/child/child_process.h" | 12 #include "content/child/child_process.h" |
| 13 #include "content/renderer/media/audio_device_factory.h" | 13 #include "content/renderer/media/audio_device_factory.h" |
| 14 #include "content/renderer/media/media_stream_audio_processor.h" | 14 #include "content/renderer/media/media_stream_audio_processor.h" |
| 15 #include "content/renderer/media/media_stream_audio_processor_options.h" | 15 #include "content/renderer/media/media_stream_audio_processor_options.h" |
| 16 #include "content/renderer/media/media_stream_audio_source.h" | |
| 16 #include "content/renderer/media/webrtc_audio_device_impl.h" | 17 #include "content/renderer/media/webrtc_audio_device_impl.h" |
| 17 #include "content/renderer/media/webrtc_local_audio_track.h" | 18 #include "content/renderer/media/webrtc_local_audio_track.h" |
| 18 #include "content/renderer/media/webrtc_logging.h" | 19 #include "content/renderer/media/webrtc_logging.h" |
| 19 #include "media/audio/sample_rates.h" | 20 #include "media/audio/sample_rates.h" |
| 20 | 21 |
| 21 namespace content { | 22 namespace content { |
| 22 | 23 |
| 23 namespace { | 24 namespace { |
| 24 | 25 |
| 25 // Supported hardware sample rates for input and output sides. | 26 // Supported hardware sample rates for input and output sides. |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 80 delegate_ = NULL; | 81 delegate_ = NULL; |
| 81 } | 82 } |
| 82 | 83 |
| 83 void Stop() { | 84 void Stop() { |
| 84 base::AutoLock lock(lock_); | 85 base::AutoLock lock(lock_); |
| 85 DCHECK(delegate_); | 86 DCHECK(delegate_); |
| 86 | 87 |
| 87 // This can be reentrant so reset |delegate_| before calling out. | 88 // This can be reentrant so reset |delegate_| before calling out. |
| 88 WebRtcLocalAudioTrack* temp = delegate_; | 89 WebRtcLocalAudioTrack* temp = delegate_; |
| 89 delegate_ = NULL; | 90 delegate_ = NULL; |
| 90 temp->Stop(); | 91 temp->StopTrack(); |
| 91 } | 92 } |
| 92 | 93 |
| 93 // Wrapper which allows to use std::find_if() when adding and removing | 94 // Wrapper which allows to use std::find_if() when adding and removing |
| 94 // sinks to/from the list. | 95 // sinks to/from the list. |
| 95 struct TrackWrapper { | 96 struct TrackWrapper { |
| 96 TrackWrapper(WebRtcLocalAudioTrack* track) : track_(track) {} | 97 TrackWrapper(WebRtcLocalAudioTrack* track) : track_(track) {} |
| 97 bool operator()( | 98 bool operator()( |
| 98 const scoped_refptr<WebRtcAudioCapturer::TrackOwner>& owner) const { | 99 const scoped_refptr<WebRtcAudioCapturer::TrackOwner>& owner) const { |
| 99 return owner->IsEqual(track_); | 100 return owner->IsEqual(track_); |
| 100 } | 101 } |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 116 WebRtcLocalAudioTrack* delegate_; | 117 WebRtcLocalAudioTrack* delegate_; |
| 117 mutable base::Lock lock_; | 118 mutable base::Lock lock_; |
| 118 | 119 |
| 119 DISALLOW_COPY_AND_ASSIGN(TrackOwner); | 120 DISALLOW_COPY_AND_ASSIGN(TrackOwner); |
| 120 }; | 121 }; |
| 121 | 122 |
| 122 // static | 123 // static |
| 123 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer( | 124 scoped_refptr<WebRtcAudioCapturer> WebRtcAudioCapturer::CreateCapturer( |
| 124 int render_view_id, const StreamDeviceInfo& device_info, | 125 int render_view_id, const StreamDeviceInfo& device_info, |
| 125 const blink::WebMediaConstraints& constraints, | 126 const blink::WebMediaConstraints& constraints, |
| 126 WebRtcAudioDeviceImpl* audio_device) { | 127 WebRtcAudioDeviceImpl* audio_device, |
| 128 MediaStreamAudioSource* audio_source) { | |
| 127 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer( | 129 scoped_refptr<WebRtcAudioCapturer> capturer = new WebRtcAudioCapturer( |
| 128 render_view_id, device_info, constraints, audio_device); | 130 render_view_id, device_info, constraints, audio_device, audio_source); |
| 129 if (capturer->Initialize()) | 131 if (capturer->Initialize()) |
| 130 return capturer; | 132 return capturer; |
| 131 | 133 |
| 132 return NULL; | 134 return NULL; |
| 133 } | 135 } |
| 134 | 136 |
| 135 bool WebRtcAudioCapturer::Initialize() { | 137 bool WebRtcAudioCapturer::Initialize() { |
| 136 DCHECK(thread_checker_.CalledOnValidThread()); | 138 DCHECK(thread_checker_.CalledOnValidThread()); |
| 137 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; | 139 DVLOG(1) << "WebRtcAudioCapturer::Initialize()"; |
| 138 WebRtcLogMessage(base::StringPrintf( | 140 WebRtcLogMessage(base::StringPrintf( |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 201 if (audio_device_) | 203 if (audio_device_) |
| 202 audio_device_->AddAudioCapturer(this); | 204 audio_device_->AddAudioCapturer(this); |
| 203 | 205 |
| 204 return true; | 206 return true; |
| 205 } | 207 } |
| 206 | 208 |
| 207 WebRtcAudioCapturer::WebRtcAudioCapturer( | 209 WebRtcAudioCapturer::WebRtcAudioCapturer( |
| 208 int render_view_id, | 210 int render_view_id, |
| 209 const StreamDeviceInfo& device_info, | 211 const StreamDeviceInfo& device_info, |
| 210 const blink::WebMediaConstraints& constraints, | 212 const blink::WebMediaConstraints& constraints, |
| 211 WebRtcAudioDeviceImpl* audio_device) | 213 WebRtcAudioDeviceImpl* audio_device, |
| 214 MediaStreamAudioSource* audio_source) | |
| 212 : constraints_(constraints), | 215 : constraints_(constraints), |
| 213 audio_processor_( | 216 audio_processor_( |
| 214 new talk_base::RefCountedObject<MediaStreamAudioProcessor>( | 217 new talk_base::RefCountedObject<MediaStreamAudioProcessor>( |
| 215 constraints, device_info.device.input.effects, | 218 constraints, device_info.device.input.effects, |
| 216 device_info.device.type, audio_device)), | 219 device_info.device.type, audio_device)), |
| 217 running_(false), | 220 running_(false), |
| 218 render_view_id_(render_view_id), | 221 render_view_id_(render_view_id), |
| 219 device_info_(device_info), | 222 device_info_(device_info), |
| 220 volume_(0), | 223 volume_(0), |
| 221 peer_connection_mode_(false), | 224 peer_connection_mode_(false), |
| 222 key_pressed_(false), | 225 key_pressed_(false), |
| 223 need_audio_processing_(false), | 226 need_audio_processing_(false), |
| 224 audio_device_(audio_device) { | 227 audio_device_(audio_device), |
| 228 audio_source_(audio_source) { | |
| 225 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; | 229 DVLOG(1) << "WebRtcAudioCapturer::WebRtcAudioCapturer()"; |
| 226 } | 230 } |
| 227 | 231 |
| 228 WebRtcAudioCapturer::~WebRtcAudioCapturer() { | 232 WebRtcAudioCapturer::~WebRtcAudioCapturer() { |
| 229 DCHECK(thread_checker_.CalledOnValidThread()); | 233 DCHECK(thread_checker_.CalledOnValidThread()); |
| 230 DCHECK(tracks_.IsEmpty()); | 234 DCHECK(tracks_.IsEmpty()); |
| 231 DCHECK(!running_); | 235 DCHECK(!running_); |
| 232 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; | 236 DVLOG(1) << "WebRtcAudioCapturer::~WebRtcAudioCapturer()"; |
| 233 } | 237 } |
| 234 | 238 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 248 } | 252 } |
| 249 | 253 |
| 250 // Start the source if the first audio track is connected to the capturer. | 254 // Start the source if the first audio track is connected to the capturer. |
| 251 // Start() will do nothing if the capturer has already been started. | 255 // Start() will do nothing if the capturer has already been started. |
| 252 Start(); | 256 Start(); |
| 253 | 257 |
| 254 } | 258 } |
| 255 | 259 |
| 256 void WebRtcAudioCapturer::RemoveTrack(WebRtcLocalAudioTrack* track) { | 260 void WebRtcAudioCapturer::RemoveTrack(WebRtcLocalAudioTrack* track) { |
| 257 DCHECK(thread_checker_.CalledOnValidThread()); | 261 DCHECK(thread_checker_.CalledOnValidThread()); |
| 258 base::AutoLock auto_lock(lock_); | 262 DVLOG(1) << "WebRtcAudioCapturer::RemoveTrack()"; |
| 263 bool stop_source = false; | |
| 264 { | |
| 265 base::AutoLock auto_lock(lock_); | |
| 259 | 266 |
| 260 scoped_refptr<TrackOwner> removed_item = | 267 scoped_refptr<TrackOwner> removed_item = |
| 261 tracks_.Remove(TrackOwner::TrackWrapper(track)); | 268 tracks_.Remove(TrackOwner::TrackWrapper(track)); |
| 262 | 269 |
| 263 // Clear the delegate to ensure that no more capture callbacks will | 270 // Clear the delegate to ensure that no more capture callbacks will |
| 264 // be sent to this sink. Also avoids a possible crash which can happen | 271 // be sent to this sink. Also avoids a possible crash which can happen |
| 265 // if this method is called while capturing is active. | 272 // if this method is called while capturing is active. |
| 266 if (removed_item.get()) | 273 if (removed_item.get()) { |
| 267 removed_item->Reset(); | 274 removed_item->Reset(); |
| 275 stop_source = tracks_.IsEmpty(); | |
| 276 } | |
|
no longer working on chromium
2014/04/01 18:29:58
you also need to set source_ to NULL to prevent st
perkj_chrome
2014/04/02 13:35:49
Please see my comment. I don't think that should b
| |
| 277 } | |
| 278 if (stop_source) { | |
|
no longer working on chromium
2014/04/01 18:29:58
nit, remove the {}
perkj_chrome
2014/04/02 13:35:49
I just added a long comment here.
| |
| 279 audio_source_->StopSource(); | |
| 280 } | |
| 268 } | 281 } |
| 269 | 282 |
| 270 void WebRtcAudioCapturer::SetCapturerSource( | 283 void WebRtcAudioCapturer::SetCapturerSource( |
| 271 const scoped_refptr<media::AudioCapturerSource>& source, | 284 const scoped_refptr<media::AudioCapturerSource>& source, |
| 272 media::ChannelLayout channel_layout, | 285 media::ChannelLayout channel_layout, |
| 273 float sample_rate) { | 286 float sample_rate) { |
| 274 DCHECK(thread_checker_.CalledOnValidThread()); | 287 DCHECK(thread_checker_.CalledOnValidThread()); |
| 275 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," | 288 DVLOG(1) << "SetCapturerSource(channel_layout=" << channel_layout << "," |
| 276 << "sample_rate=" << sample_rate << ")"; | 289 << "sample_rate=" << sample_rate << ")"; |
| 277 scoped_refptr<media::AudioCapturerSource> old_source; | 290 scoped_refptr<media::AudioCapturerSource> old_source; |
| (...skipping 302 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 580 DCHECK_NE(aec_dump_file, base::kInvalidPlatformFileValue); | 593 DCHECK_NE(aec_dump_file, base::kInvalidPlatformFileValue); |
| 581 audio_processor_->StartAecDump(aec_dump_file); | 594 audio_processor_->StartAecDump(aec_dump_file); |
| 582 } | 595 } |
| 583 | 596 |
| 584 void WebRtcAudioCapturer::StopAecDump() { | 597 void WebRtcAudioCapturer::StopAecDump() { |
| 585 DCHECK(thread_checker_.CalledOnValidThread()); | 598 DCHECK(thread_checker_.CalledOnValidThread()); |
| 586 audio_processor_->StopAecDump(); | 599 audio_processor_->StopAecDump(); |
| 587 } | 600 } |
| 588 | 601 |
| 589 } // namespace content | 602 } // namespace content |
| OLD | NEW |