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_renderer.h" | 5 #include "content/renderer/media/webrtc_local_audio_renderer.h" |
6 | 6 |
7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
8 #include "base/logging.h" | 8 #include "base/logging.h" |
9 #include "base/message_loop_proxy.h" | 9 #include "base/message_loop_proxy.h" |
10 #include "base/synchronization/lock.h" | 10 #include "base/synchronization/lock.h" |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
91 int source_render_view_id) | 91 int source_render_view_id) |
92 : audio_track_(audio_track), | 92 : audio_track_(audio_track), |
93 source_render_view_id_(source_render_view_id), | 93 source_render_view_id_(source_render_view_id), |
94 playing_(false) { | 94 playing_(false) { |
95 DCHECK(audio_track); | 95 DCHECK(audio_track); |
96 DVLOG(1) << "WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer()"; | 96 DVLOG(1) << "WebRtcLocalAudioRenderer::WebRtcLocalAudioRenderer()"; |
97 } | 97 } |
98 | 98 |
99 WebRtcLocalAudioRenderer::~WebRtcLocalAudioRenderer() { | 99 WebRtcLocalAudioRenderer::~WebRtcLocalAudioRenderer() { |
100 DCHECK(thread_checker_.CalledOnValidThread()); | 100 DCHECK(thread_checker_.CalledOnValidThread()); |
101 DCHECK(!sink_); | 101 DCHECK(!sink_.get()); |
102 DVLOG(1) << "WebRtcLocalAudioRenderer::~WebRtcLocalAudioRenderer()"; | 102 DVLOG(1) << "WebRtcLocalAudioRenderer::~WebRtcLocalAudioRenderer()"; |
103 } | 103 } |
104 | 104 |
105 void WebRtcLocalAudioRenderer::Start() { | 105 void WebRtcLocalAudioRenderer::Start() { |
106 DVLOG(1) << "WebRtcLocalAudioRenderer::Start()"; | 106 DVLOG(1) << "WebRtcLocalAudioRenderer::Start()"; |
107 DCHECK(thread_checker_.CalledOnValidThread()); | 107 DCHECK(thread_checker_.CalledOnValidThread()); |
108 // Add this class as sink to the audio track to ensure that we receive | 108 // Add this class as sink to the audio track to ensure that we receive |
109 // WebRtcAudioCapturerSink::CaptureData() callbacks for captured audio. | 109 // WebRtcAudioCapturerSink::CaptureData() callbacks for captured audio. |
110 // |audio_params_| will be updated right after the AddCapturerAudioTrack(). | 110 // |audio_params_| will be updated right after the AddCapturerAudioTrack(). |
111 audio_track_->AddSink(this); | 111 audio_track_->AddSink(this); |
112 | 112 |
113 base::AutoLock auto_lock(thread_lock_); | 113 base::AutoLock auto_lock(thread_lock_); |
114 DCHECK(!sink_); | 114 DCHECK(!sink_.get()); |
115 | 115 |
116 // TODO(henrika): we could add a more dynamic solution here but I prefer | 116 // TODO(henrika): we could add a more dynamic solution here but I prefer |
117 // a fixed size combined with bad audio at overflow. The alternative is | 117 // a fixed size combined with bad audio at overflow. The alternative is |
118 // that we start to build up latency and that can be more difficult to | 118 // that we start to build up latency and that can be more difficult to |
119 // detect. Tests have shown that the FIFO never contains more than 2 or 3 | 119 // detect. Tests have shown that the FIFO never contains more than 2 or 3 |
120 // audio frames but I have selected a max size of ten buffers just | 120 // audio frames but I have selected a max size of ten buffers just |
121 // in case since these tests were performed on a 16 core, 64GB Win 7 | 121 // in case since these tests were performed on a 16 core, 64GB Win 7 |
122 // machine. We could also add some sort of error notifier in this area if | 122 // machine. We could also add some sort of error notifier in this area if |
123 // the FIFO overflows. | 123 // the FIFO overflows. |
124 DCHECK(!loopback_fifo_); | 124 DCHECK(!loopback_fifo_); |
(...skipping 17 matching lines...) Expand all Loading... |
142 sink_->Start(); | 142 sink_->Start(); |
143 | 143 |
144 last_render_time_ = base::Time::Now(); | 144 last_render_time_ = base::Time::Now(); |
145 playing_ = false; | 145 playing_ = false; |
146 } | 146 } |
147 | 147 |
148 void WebRtcLocalAudioRenderer::Stop() { | 148 void WebRtcLocalAudioRenderer::Stop() { |
149 DVLOG(1) << "WebRtcLocalAudioRenderer::Stop()"; | 149 DVLOG(1) << "WebRtcLocalAudioRenderer::Stop()"; |
150 DCHECK(thread_checker_.CalledOnValidThread()); | 150 DCHECK(thread_checker_.CalledOnValidThread()); |
151 | 151 |
152 if (!sink_) | 152 if (!sink_.get()) |
153 return; | 153 return; |
154 | 154 |
155 { | 155 { |
156 base::AutoLock auto_lock(thread_lock_); | 156 base::AutoLock auto_lock(thread_lock_); |
157 playing_ = false; | 157 playing_ = false; |
158 | 158 |
159 if (loopback_fifo_.get() != NULL) { | 159 if (loopback_fifo_.get() != NULL) { |
160 loopback_fifo_->Clear(); | 160 loopback_fifo_->Clear(); |
161 loopback_fifo_.reset(); | 161 loopback_fifo_.reset(); |
162 } | 162 } |
163 } | 163 } |
164 | 164 |
165 // Stop the output audio stream, i.e, stop asking for data to render. | 165 // Stop the output audio stream, i.e, stop asking for data to render. |
166 sink_->Stop(); | 166 sink_->Stop(); |
167 sink_ = NULL; | 167 sink_ = NULL; |
168 | 168 |
169 // Ensure that the capturer stops feeding us with captured audio. | 169 // Ensure that the capturer stops feeding us with captured audio. |
170 // Note that, we do not stop the capturer here since it may still be used by | 170 // Note that, we do not stop the capturer here since it may still be used by |
171 // the WebRTC ADM. | 171 // the WebRTC ADM. |
172 audio_track_->RemoveSink(this); | 172 audio_track_->RemoveSink(this); |
173 audio_track_ = NULL; | 173 audio_track_ = NULL; |
174 } | 174 } |
175 | 175 |
176 void WebRtcLocalAudioRenderer::Play() { | 176 void WebRtcLocalAudioRenderer::Play() { |
177 DVLOG(1) << "WebRtcLocalAudioRenderer::Play()"; | 177 DVLOG(1) << "WebRtcLocalAudioRenderer::Play()"; |
178 DCHECK(thread_checker_.CalledOnValidThread()); | 178 DCHECK(thread_checker_.CalledOnValidThread()); |
179 base::AutoLock auto_lock(thread_lock_); | 179 base::AutoLock auto_lock(thread_lock_); |
180 | 180 |
181 if (!sink_) | 181 if (!sink_.get()) |
182 return; | 182 return; |
183 | 183 |
184 // Resumes rendering by ensuring that WebRtcLocalAudioRenderer::Render() | 184 // Resumes rendering by ensuring that WebRtcLocalAudioRenderer::Render() |
185 // now reads data from the local FIFO. | 185 // now reads data from the local FIFO. |
186 playing_ = true; | 186 playing_ = true; |
187 last_render_time_ = base::Time::Now(); | 187 last_render_time_ = base::Time::Now(); |
188 | 188 |
189 if (loopback_fifo_) | 189 if (loopback_fifo_) |
190 loopback_fifo_->Clear(); | 190 loopback_fifo_->Clear(); |
191 } | 191 } |
192 | 192 |
193 void WebRtcLocalAudioRenderer::Pause() { | 193 void WebRtcLocalAudioRenderer::Pause() { |
194 DVLOG(1) << "WebRtcLocalAudioRenderer::Pause()"; | 194 DVLOG(1) << "WebRtcLocalAudioRenderer::Pause()"; |
195 DCHECK(thread_checker_.CalledOnValidThread()); | 195 DCHECK(thread_checker_.CalledOnValidThread()); |
196 base::AutoLock auto_lock(thread_lock_); | 196 base::AutoLock auto_lock(thread_lock_); |
197 | 197 |
198 if (!sink_) | 198 if (!sink_.get()) |
199 return; | 199 return; |
200 | 200 |
201 // Temporarily suspends rendering audio. | 201 // Temporarily suspends rendering audio. |
202 // WebRtcLocalAudioRenderer::Render() will return early during this state | 202 // WebRtcLocalAudioRenderer::Render() will return early during this state |
203 // and only zeros will be provided to the active sink. | 203 // and only zeros will be provided to the active sink. |
204 playing_ = false; | 204 playing_ = false; |
205 } | 205 } |
206 | 206 |
207 void WebRtcLocalAudioRenderer::SetVolume(float volume) { | 207 void WebRtcLocalAudioRenderer::SetVolume(float volume) { |
208 DVLOG(1) << "WebRtcLocalAudioRenderer::SetVolume(" << volume << ")"; | 208 DVLOG(1) << "WebRtcLocalAudioRenderer::SetVolume(" << volume << ")"; |
209 DCHECK(thread_checker_.CalledOnValidThread()); | 209 DCHECK(thread_checker_.CalledOnValidThread()); |
210 base::AutoLock auto_lock(thread_lock_); | 210 base::AutoLock auto_lock(thread_lock_); |
211 if (sink_) | 211 if (sink_.get()) |
212 sink_->SetVolume(volume); | 212 sink_->SetVolume(volume); |
213 } | 213 } |
214 | 214 |
215 base::TimeDelta WebRtcLocalAudioRenderer::GetCurrentRenderTime() const { | 215 base::TimeDelta WebRtcLocalAudioRenderer::GetCurrentRenderTime() const { |
216 DCHECK(thread_checker_.CalledOnValidThread()); | 216 DCHECK(thread_checker_.CalledOnValidThread()); |
217 base::AutoLock auto_lock(thread_lock_); | 217 base::AutoLock auto_lock(thread_lock_); |
218 if (!sink_) | 218 if (!sink_.get()) |
219 return base::TimeDelta(); | 219 return base::TimeDelta(); |
220 return total_render_time(); | 220 return total_render_time(); |
221 } | 221 } |
222 | 222 |
223 bool WebRtcLocalAudioRenderer::IsLocalRenderer() const { | 223 bool WebRtcLocalAudioRenderer::IsLocalRenderer() const { |
224 return true; | 224 return true; |
225 } | 225 } |
226 | 226 |
227 } // namespace content | 227 } // namespace content |
OLD | NEW |