| 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) |
| 23 : MediaStreamTrack(adapter, true), | 22 : MediaStreamTrack(adapter, true), |
| 24 adapter_(adapter), | 23 adapter_(adapter), |
| 25 capturer_(capturer), | 24 capturer_(capturer), |
| 26 webaudio_source_(webaudio_source) { | 25 webaudio_source_(webaudio_source) { |
| 27 DCHECK(capturer.get() || webaudio_source); | 26 DCHECK(capturer.get() || webaudio_source); |
| 28 | 27 |
| 29 adapter_->Initialize(this); | 28 adapter_->Initialize(this); |
| 30 | 29 |
| 31 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()"; | 30 DVLOG(1) << "WebRtcLocalAudioTrack::WebRtcLocalAudioTrack()"; |
| 32 } | 31 } |
| 33 | 32 |
| 34 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { | 33 WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack() { |
| 35 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 34 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 36 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; | 35 DVLOG(1) << "WebRtcLocalAudioTrack::~WebRtcLocalAudioTrack()"; |
| 37 // Users might not call Stop() on the track. | 36 // Users might not call Stop() on the track. |
| 38 Stop(); | 37 Stop(); |
| 39 } | 38 } |
| 40 | 39 |
| 41 void WebRtcLocalAudioTrack::Capture(const int16* audio_data, | 40 void WebRtcLocalAudioTrack::Capture(const int16* audio_data, |
| 42 base::TimeDelta delay, | |
| 43 int volume, | |
| 44 bool key_pressed, | |
| 45 bool need_audio_processing, | |
| 46 bool force_report_nonzero_energy) { | 41 bool force_report_nonzero_energy) { |
| 47 DCHECK(capture_thread_checker_.CalledOnValidThread()); | 42 DCHECK(capture_thread_checker_.CalledOnValidThread()); |
| 48 | 43 |
| 49 // Calculate the signal level regardless if the track is disabled or enabled. | 44 // Calculate the signal level regardless if the track is disabled or enabled. |
| 50 int signal_level = level_calculator_->Calculate( | 45 int signal_level = level_calculator_->Calculate( |
| 51 audio_data, audio_parameters_.channels(), | 46 audio_data, audio_parameters_.channels(), |
| 52 audio_parameters_.frames_per_buffer(), force_report_nonzero_energy); | 47 audio_parameters_.frames_per_buffer(), force_report_nonzero_energy); |
| 53 adapter_->SetSignalLevel(signal_level); | 48 adapter_->SetSignalLevel(signal_level); |
| 54 | 49 |
| 55 scoped_refptr<WebRtcAudioCapturer> capturer; | 50 scoped_refptr<WebRtcAudioCapturer> capturer; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 71 | 66 |
| 72 // Feed the data to the sinks. | 67 // Feed the data to the sinks. |
| 73 // TODO(jiayl): we should not pass the real audio data down if the track is | 68 // TODO(jiayl): we should not pass the real audio data down if the track is |
| 74 // disabled. This is currently done so to feed input to WebRTC typing | 69 // disabled. This is currently done so to feed input to WebRTC typing |
| 75 // detection and should be changed when audio processing is moved from | 70 // detection and should be changed when audio processing is moved from |
| 76 // WebRTC to the track. | 71 // WebRTC to the track. |
| 77 std::vector<int> voe_channels = adapter_->VoeChannels(); | 72 std::vector<int> voe_channels = adapter_->VoeChannels(); |
| 78 for (SinkList::ItemList::const_iterator it = sinks.begin(); | 73 for (SinkList::ItemList::const_iterator it = sinks.begin(); |
| 79 it != sinks.end(); | 74 it != sinks.end(); |
| 80 ++it) { | 75 ++it) { |
| 81 int new_volume = (*it)->OnData(audio_data, | 76 (*it)->OnData(audio_data, audio_parameters_.sample_rate(), |
| 82 audio_parameters_.sample_rate(), | 77 audio_parameters_.channels(), |
| 83 audio_parameters_.channels(), | 78 audio_parameters_.frames_per_buffer()); |
| 84 audio_parameters_.frames_per_buffer(), | |
| 85 voe_channels, | |
| 86 delay.InMilliseconds(), | |
| 87 volume, | |
| 88 need_audio_processing, | |
| 89 key_pressed); | |
| 90 if (new_volume != 0 && capturer.get() && !webaudio_source_.get()) { | |
| 91 // Feed the new volume to WebRtc while changing the volume on the | |
| 92 // browser. | |
| 93 capturer->SetVolume(new_volume); | |
| 94 } | |
| 95 } | 79 } |
| 96 } | 80 } |
| 97 | 81 |
| 98 void WebRtcLocalAudioTrack::OnSetFormat( | 82 void WebRtcLocalAudioTrack::OnSetFormat( |
| 99 const media::AudioParameters& params) { | 83 const media::AudioParameters& params) { |
| 100 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()"; | 84 DVLOG(1) << "WebRtcLocalAudioTrack::OnSetFormat()"; |
| 101 // If the source is restarted, we might have changed to another capture | 85 // If the source is restarted, we might have changed to another capture |
| 102 // thread. | 86 // thread. |
| 103 capture_thread_checker_.DetachFromThread(); | 87 capture_thread_checker_.DetachFromThread(); |
| 104 DCHECK(capture_thread_checker_.CalledOnValidThread()); | 88 DCHECK(capture_thread_checker_.CalledOnValidThread()); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 148 scoped_refptr<MediaStreamAudioTrackSink> removed_item = sinks_.Remove( | 132 scoped_refptr<MediaStreamAudioTrackSink> removed_item = sinks_.Remove( |
| 149 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)); | 133 MediaStreamAudioTrackSink::WrapsMediaStreamSink(sink)); |
| 150 | 134 |
| 151 // Clear the delegate to ensure that no more capture callbacks will | 135 // Clear the delegate to ensure that no more capture callbacks will |
| 152 // be sent to this sink. Also avoids a possible crash which can happen | 136 // be sent to this sink. Also avoids a possible crash which can happen |
| 153 // if this method is called while capturing is active. | 137 // if this method is called while capturing is active. |
| 154 if (removed_item.get()) | 138 if (removed_item.get()) |
| 155 removed_item->Reset(); | 139 removed_item->Reset(); |
| 156 } | 140 } |
| 157 | 141 |
| 158 void WebRtcLocalAudioTrack::AddSink(PeerConnectionAudioSink* sink) { | |
| 159 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | |
| 160 DVLOG(1) << "WebRtcLocalAudioTrack::AddSink()"; | |
| 161 base::AutoLock auto_lock(lock_); | |
| 162 | |
| 163 // Verify that |sink| is not already added to the list. | |
| 164 DCHECK(!sinks_.Contains( | |
| 165 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink))); | |
| 166 | |
| 167 // Create (and add to the list) a new MediaStreamAudioTrackSink | |
| 168 // which owns the |sink| and delagates all calls to the | |
| 169 // MediaStreamAudioSink interface. It will be tagged in the list, so | |
| 170 // we remember to call OnSetFormat() on the new sink. | |
| 171 scoped_refptr<MediaStreamAudioTrackSink> sink_owner( | |
| 172 new PeerConnectionAudioSinkOwner(sink)); | |
| 173 sinks_.AddAndTag(sink_owner.get()); | |
| 174 } | |
| 175 | |
| 176 void WebRtcLocalAudioTrack::RemoveSink(PeerConnectionAudioSink* sink) { | |
| 177 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | |
| 178 DVLOG(1) << "WebRtcLocalAudioTrack::RemoveSink()"; | |
| 179 | |
| 180 base::AutoLock auto_lock(lock_); | |
| 181 | |
| 182 scoped_refptr<MediaStreamAudioTrackSink> removed_item = sinks_.Remove( | |
| 183 MediaStreamAudioTrackSink::WrapsPeerConnectionSink(sink)); | |
| 184 // Clear the delegate to ensure that no more capture callbacks will | |
| 185 // be sent to this sink. Also avoids a possible crash which can happen | |
| 186 // if this method is called while capturing is active. | |
| 187 if (removed_item.get()) | |
| 188 removed_item->Reset(); | |
| 189 } | |
| 190 | |
| 191 void WebRtcLocalAudioTrack::Start() { | 142 void WebRtcLocalAudioTrack::Start() { |
| 192 DCHECK(main_render_thread_checker_.CalledOnValidThread()); | 143 DCHECK(main_render_thread_checker_.CalledOnValidThread()); |
| 193 DVLOG(1) << "WebRtcLocalAudioTrack::Start()"; | 144 DVLOG(1) << "WebRtcLocalAudioTrack::Start()"; |
| 194 if (webaudio_source_.get()) { | 145 if (webaudio_source_.get()) { |
| 195 // If the track is hooking up with WebAudio, do NOT add the track to the | 146 // If the track is hooking up with WebAudio, do NOT add the track to the |
| 196 // capturer as its sink otherwise two streams in different clock will be | 147 // capturer as its sink otherwise two streams in different clock will be |
| 197 // pushed through the same track. | 148 // pushed through the same track. |
| 198 webaudio_source_->Start(this, capturer_.get()); | 149 webaudio_source_->Start(this); |
| 199 } else if (capturer_.get()) { | 150 } else if (capturer_.get()) { |
| 200 capturer_->AddTrack(this); | 151 capturer_->AddTrack(this); |
| 201 } | 152 } |
| 202 | 153 |
| 203 SinkList::ItemList sinks; | 154 SinkList::ItemList sinks; |
| 204 { | 155 { |
| 205 base::AutoLock auto_lock(lock_); | 156 base::AutoLock auto_lock(lock_); |
| 206 sinks = sinks_.Items(); | 157 sinks = sinks_.Items(); |
| 207 } | 158 } |
| 208 for (SinkList::ItemList::const_iterator it = sinks.begin(); | 159 for (SinkList::ItemList::const_iterator it = sinks.begin(); |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 | 194 |
| 244 for (SinkList::ItemList::const_iterator it = sinks.begin(); | 195 for (SinkList::ItemList::const_iterator it = sinks.begin(); |
| 245 it != sinks.end(); | 196 it != sinks.end(); |
| 246 ++it){ | 197 ++it){ |
| 247 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); | 198 (*it)->OnReadyStateChanged(blink::WebMediaStreamSource::ReadyStateEnded); |
| 248 (*it)->Reset(); | 199 (*it)->Reset(); |
| 249 } | 200 } |
| 250 } | 201 } |
| 251 | 202 |
| 252 } // namespace content | 203 } // namespace content |
| OLD | NEW |