| 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_local_audio_track.h" | 5 #include "content/renderer/media/webrtc_local_audio_track.h" |
| 6 | 6 |
| 7 #include "content/public/renderer/media_stream_audio_sink.h" | 7 #include "content/public/renderer/media_stream_audio_sink.h" |
| 8 #include "content/renderer/media/media_stream_audio_level_calculator.h" | 8 #include "content/renderer/media/media_stream_audio_level_calculator.h" |
| 9 #include "content/renderer/media/media_stream_audio_processor.h" | 9 #include "content/renderer/media/media_stream_audio_processor.h" |
| 10 #include "content/renderer/media/media_stream_audio_sink_owner.h" | 10 #include "content/renderer/media/media_stream_audio_sink_owner.h" |
| 11 #include "content/renderer/media/media_stream_audio_track_sink.h" | 11 #include "content/renderer/media/media_stream_audio_track_sink.h" |
| 12 #include "content/renderer/media/peer_connection_audio_sink_owner.h" | |
| 13 #include "content/renderer/media/webaudio_capturer_source.h" | 12 #include "content/renderer/media/webaudio_capturer_source.h" |
| 14 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" | 13 #include "content/renderer/media/webrtc/webrtc_local_audio_track_adapter.h" |
| 15 #include "content/renderer/media/webrtc_audio_capturer.h" | 14 #include "content/renderer/media/webrtc_audio_capturer.h" |
| 16 | 15 |
| 17 namespace content { | 16 namespace content { |
| 18 | 17 |
| 19 WebRtcLocalAudioTrack::WebRtcLocalAudioTrack( | 18 WebRtcLocalAudioTrack::WebRtcLocalAudioTrack( |
| 20 WebRtcLocalAudioTrackAdapter* adapter, | 19 WebRtcLocalAudioTrackAdapter* adapter, |
| 21 const scoped_refptr<WebRtcAudioCapturer>& capturer, | 20 const scoped_refptr<WebRtcAudioCapturer>& capturer, |
| 22 WebAudioCapturerSource* webaudio_source) | 21 WebAudioCapturerSource* webaudio_source) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 33 } | 32 } |
| 34 | 33 |
| 35 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { | 34 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { |
| 36 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 35 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 37 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; | 36 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; |
| 38 // Users might not call Stop() on the track. | 37 // Users might not call Stop() on the track. |
| 39 Stop(); | 38 Stop(); |
| 40 } | 39 } |
| 41 | 40 |
| 42 void WebRtcLocalAudioTrack::Capture(const int16* audio_data, | 41 void WebRtcLocalAudioTrack::Capture(const int16* audio_data, |
| 43 base::TimeDelta delay, | |
| 44 int volume, | |
| 45 bool key_pressed, | |
| 46 bool need_audio_processing, | |
| 47 bool force_report_nonzero_energy) { | 42 bool force_report_nonzero_energy) { |
| 48 DCHECK(capture_thread_checker_.CalledOnValidThread()); | 43 DCHECK(capture_thread_checker_.CalledOnValidThread()); |
| 49 | 44 |
| 50 // Calculate the signal level regardless if the track is disabled or enabled. | 45 // Calculate the signal level regardless if the track is disabled or enabled. |
| 51 int signal_level = level_calculator_->Calculate( | 46 int signal_level = level_calculator_->Calculate( |
| 52 audio_data, audio_parameters_.channels(), | 47 audio_data, audio_parameters_.channels(), |
| 53 audio_parameters_.frames_per_buffer(), force_report_nonzero_energy); | 48 audio_parameters_.frames_per_buffer(), force_report_nonzero_energy); |
| 54 adapter_->SetSignalLevel(signal_level); | 49 adapter_->SetSignalLevel(signal_level); |
| 55 | 50 |
| 56 scoped_refptr<WebRtcAudioCapturer> capturer; | 51 scoped_refptr<WebRtcAudioCapturer> capturer; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 72 | 67 |
| 73 // Feed the data to the sinks. | 68 // Feed the data to the sinks. |
| 74 // TODO(jiayl): we should not pass the real audio data down if the track is | 69 // TODO(jiayl): we should not pass the real audio data down if the track is |
| 75 // disabled. This is currently done so to feed input to WebRTC typing | 70 // disabled. This is currently done so to feed input to WebRTC typing |
| 76 // detection and should be changed when audio processing is moved from | 71 // detection and should be changed when audio processing is moved from |
| 77 // WebRTC to the track. | 72 // WebRTC to the track. |
| 78 std::vector<int> voe_channels = adapter_->VoeChannels(); | 73 std::vector<int> voe_channels = adapter_->VoeChannels(); |
| 79 for (SinkList::ItemList::const_iterator it = sinks.begin(); | 74 for (SinkList::ItemList::const_iterator it = sinks.begin(); |
| 80 it != sinks.end(); | 75 it != sinks.end(); |
| 81 ++it) { | 76 ++it) { |
| 82 int new_volume = (*it)->OnData(audio_data, | 77 (*it)->OnData(audio_data, audio_parameters_.sample_rate(), |
| 83 audio_parameters_.sample_rate(), | 78 audio_parameters_.channels(), |
| 84 audio_parameters_.channels(), | 79 audio_parameters_.frames_per_buffer()); |
| 85 audio_parameters_.frames_per_buffer(), | |
| 86 voe_channels, | |
| 87 delay.InMilliseconds(), | |
| 88 volume, | |
| 89 need_audio_processing, | |
| 90 key_pressed); | |
| 91 if (new_volume != 0 && capturer.get() && !webaudio_source_.get()) { | |
| 92 // Feed the new volume to WebRtc while changing the volume on the | |
| 93 // browser. | |
| 94 capturer->SetVolume(new_volume); | |
| 95 } | |
| 96 } | 80 } |
| 97 } | 81 } |
| 98 | 82 |
| 99 void WebRtcLocalAudioTrack::OnSetFormat( | 83 void WebRtcLocalAudioTrack::OnSetFormat( |
| 100 const media::AudioParameters& params) { | 84 const media::AudioParameters& params) { |
| 101 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()"; | 85 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()"; |
| 102 // If the source is restarted, we might have changed to another capture | 86 // If the source is restarted, we might have changed to another capture |
| 103 // thread. | 87 // thread. |
| 104 capture_thread_checker_.DetachFromThread(); | 88 capture_thread_checker_.DetachFromThread(); |
| 105 DCHECK(capture_thread_checker_.CalledOnValidThread()); | 89 DCHECK(capture_thread_checker_.CalledOnValidThread()); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 158 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)); | 142 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)); |
| 159 } | 143 } |
| 160 | 144 |
| 161 // Clear the delegate to ensure that no more capture callbacks will | 145 // Clear the delegate to ensure that no more capture callbacks will |
| 162 // be sent to this sink. Also avoids a possible crash which can happen | 146 // be sent to this sink. Also avoids a possible crash which can happen |
| 163 // if this method is called while capturing is active. | 147 // if this method is called while capturing is active. |
| 164 if (removed_item.get()) | 148 if (removed_item.get()) |
| 165 removed_item->Reset(); | 149 removed_item->Reset(); |
| 166 } | 150 } |
| 167 | 151 |
| 168 void WebRtcLocalAudioTrack::AddSink(PeerConnectionAudioSink* sink) { | |
| 169 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | |
| 170 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()"; | |
| 171 base::AutoLock auto_lock(lock_); | |
| 172 | |
| 173 // Verify that |sink| is not already added to the list. | |
| 174 DCHECK(!sinks_.Contains( | |
| 175 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink))); | |
| 176 | |
| 177 // Create (and add to the list) a new MediaStreamAudioTrackSink | |
| 178 // which owns the |sink| and delagates all calls to the | |
| 179 // MediaStreamAudioSink interface. It will be tagged in the list, so | |
| 180 // we remember to call OnSetFormat() on the new sink. | |
| 181 scoped_refptr<MediaStreamAudioTrackSink> sink_owner( | |
| 182 new PeerConnectionAudioSinkOwner(sink)); | |
| 183 sinks_.AddAndTag(sink_owner.get()); | |
| 184 } | |
| 185 | |
| 186 void WebRtcLocalAudioTrack::RemoveSink(PeerConnectionAudioSink* sink) { | |
| 187 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | |
| 188 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveSink()"; | |
| 189 | |
| 190 base::AutoLock auto_lock(lock_); | |
| 191 | |
| 192 scoped_refptr<MediaStreamAudioTrackSink> removed_item = sinks_.Remove( | |
| 193 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink)); | |
| 194 // Clear the delegate to ensure that no more capture callbacks will | |
| 195 // be sent to this sink. Also avoids a possible crash which can happen | |
| 196 // if this method is called while capturing is active. | |
| 197 if (removed_item.get()) | |
| 198 removed_item->Reset(); | |
| 199 } | |
| 200 | |
| 201 void WebRtcLocalAudioTrack::Start() { | 152 void WebRtcLocalAudioTrack::Start() { |
| 202 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 153 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 203 DVLOG(1) << "WebRtcLocalAudioTrack::Start()"; | 154 DVLOG(1) << "WebRtcLocalAudioTrack::Start()"; |
| 204 if (webaudio_source_.get()) { | 155 if (webaudio_source_.get()) { |
| 205 // If the track is hooking up with WebAudio, do NOT add the track to the | 156 // If the track is hooking up with WebAudio, do NOT add the track to the |
| 206 // capturer as its sink otherwise two streams in different clock will be | 157 // capturer as its sink otherwise two streams in different clock will be |
| 207 // pushed through the same track. | 158 // pushed through the same track. |
| 208 webaudio_source_->Start(this, capturer_.get()); | 159 webaudio_source_->Start(this); |
| 209 } else if (capturer_.get()) { | 160 } else if (capturer_.get()) { |
| 210 capturer_->AddTrack(this); | 161 capturer_->AddTrack(this); |
| 211 } | 162 } |
| 212 | 163 |
| 213 SinkList::ItemList sinks; | 164 SinkList::ItemList sinks; |
| 214 { | 165 { |
| 215 base::AutoLock auto_lock(lock_); | 166 base::AutoLock auto_lock(lock_); |
| 216 sinks = sinks_.Items(); | 167 sinks = sinks_.Items(); |
| 217 } | 168 } |
| 218 for (SinkList::ItemList::const_iterator it = sinks.begin(); | 169 for (SinkList::ItemList::const_iterator it = sinks.begin(); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 (*it)->Reset(); | 215 (*it)->Reset(); |
| 265 } | 216 } |
| 266 } | 217 } |
| 267 | 218 |
| 268 webrtc::AudioTrackInterface* WebRtcLocalAudioTrack::GetAudioAdapter() { | 219 webrtc::AudioTrackInterface* WebRtcLocalAudioTrack::GetAudioAdapter() { |
| 269 DCHECK(thread_checker_.CalledOnValidThread()); | 220 DCHECK(thread_checker_.CalledOnValidThread()); |
| 270 return adapter_.get(); | 221 return adapter_.get(); |
| 271 } | 222 } |
| 272 | 223 |
| 273 } // namespace content | 224 } // namespace content |
| OLD | NEW |