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 |