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/audio_device.h" | 5 #include "content/renderer/media/audio_device.h" |
6 | 6 |
7 #include "base/bind.h" | 7 #include "base/bind.h" |
8 #include "base/debug/trace_event.h" | 8 #include "base/debug/trace_event.h" |
9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
10 #include "base/threading/thread_restrictions.h" | 10 #include "base/threading/thread_restrictions.h" |
11 #include "base/time.h" | 11 #include "base/time.h" |
12 #include "content/common/child_process.h" | 12 #include "content/common/child_process.h" |
13 #include "content/common/media/audio_messages.h" | 13 #include "content/common/media/audio_messages.h" |
14 #include "content/common/view_messages.h" | 14 #include "content/common/view_messages.h" |
15 #include "content/renderer/render_thread_impl.h" | 15 #include "content/renderer/render_thread_impl.h" |
16 #include "media/audio/audio_output_controller.h" | 16 #include "media/audio/audio_output_controller.h" |
17 #include "media/audio/audio_util.h" | 17 #include "media/audio/audio_util.h" |
18 | 18 |
19 AudioDevice::AudioDevice() | 19 AudioDevice::AudioDevice() |
20 : buffer_size_(0), | 20 : buffer_size_(0), |
21 channels_(0), | 21 channels_(0), |
22 bits_per_sample_(16), | 22 bits_per_sample_(16), |
23 sample_rate_(0), | 23 sample_rate_(0), |
24 latency_format_(AudioParameters::AUDIO_PCM_LOW_LATENCY), | 24 latency_format_(AudioParameters::AUDIO_PCM_LOW_LATENCY), |
scherkus (not reviewing)
2012/02/01 22:56:12
does this also need to get updated?
is this alway
vrk (LEFT CHROMIUM)
2012/02/02 21:05:41
Ooh, I didn't even notice this! Looked into this a
| |
25 callback_(0), | 25 callback_(0), |
26 is_initialized_(false), | 26 is_initialized_(false), |
27 audio_delay_milliseconds_(0), | 27 audio_delay_milliseconds_(0), |
28 volume_(1.0), | 28 volume_(1.0), |
29 stream_id_(0), | 29 stream_id_(0), |
30 play_on_start_(true), | 30 play_on_start_(true), |
31 is_started_(false), | 31 is_started_(false), |
32 shared_memory_handle_(base::SharedMemory::NULLHandle()), | 32 shared_memory_handle_(base::SharedMemory::NULLHandle()), |
33 memory_length_(0) { | 33 memory_length_(0) { |
34 filter_ = RenderThreadImpl::current()->audio_message_filter(); | 34 filter_ = RenderThreadImpl::current()->audio_message_filter(); |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 } | 151 } |
152 | 152 |
153 void AudioDevice::InitializeOnIOThread(const AudioParameters& params) { | 153 void AudioDevice::InitializeOnIOThread(const AudioParameters& params) { |
154 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); | 154 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); |
155 // Make sure we don't create the stream more than once. | 155 // Make sure we don't create the stream more than once. |
156 DCHECK_EQ(0, stream_id_); | 156 DCHECK_EQ(0, stream_id_); |
157 if (stream_id_) | 157 if (stream_id_) |
158 return; | 158 return; |
159 | 159 |
160 stream_id_ = filter_->AddDelegate(this); | 160 stream_id_ = filter_->AddDelegate(this); |
161 Send(new AudioHostMsg_CreateStream(stream_id_, params, true)); | 161 Send(new AudioHostMsg_CreateStream(stream_id_, params)); |
162 } | 162 } |
163 | 163 |
164 void AudioDevice::PlayOnIOThread() { | 164 void AudioDevice::PlayOnIOThread() { |
165 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); | 165 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); |
166 if (stream_id_ && is_started_) | 166 if (stream_id_ && is_started_) |
167 Send(new AudioHostMsg_PlayStream(stream_id_)); | 167 Send(new AudioHostMsg_PlayStream(stream_id_)); |
168 else | 168 else |
169 play_on_start_ = true; | 169 play_on_start_ = true; |
170 } | 170 } |
171 | 171 |
(...skipping 26 matching lines...) Expand all Loading... | |
198 | 198 |
199 signal->Signal(); | 199 signal->Signal(); |
200 } | 200 } |
201 | 201 |
202 void AudioDevice::SetVolumeOnIOThread(double volume) { | 202 void AudioDevice::SetVolumeOnIOThread(double volume) { |
203 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); | 203 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); |
204 if (stream_id_) | 204 if (stream_id_) |
205 Send(new AudioHostMsg_SetVolume(stream_id_, volume)); | 205 Send(new AudioHostMsg_SetVolume(stream_id_, volume)); |
206 } | 206 } |
207 | 207 |
208 void AudioDevice::OnRequestPacket(AudioBuffersState buffers_state) { | |
209 // This method does not apply to the low-latency system. | |
210 } | |
211 | |
212 void AudioDevice::OnStateChanged(AudioStreamState state) { | 208 void AudioDevice::OnStateChanged(AudioStreamState state) { |
213 if (state == kAudioStreamError) { | 209 if (state == kAudioStreamError) { |
214 DLOG(WARNING) << "AudioDevice::OnStateChanged(kError)"; | 210 DLOG(WARNING) << "AudioDevice::OnStateChanged(kError)"; |
215 callback_->OnError(); | 211 callback_->OnError(); |
216 } | 212 } |
217 } | 213 } |
218 | 214 |
219 void AudioDevice::OnCreated( | 215 void AudioDevice::OnStreamCreated( |
220 base::SharedMemoryHandle handle, uint32 length) { | |
221 // Not needed in this simple implementation. | |
222 } | |
223 | |
224 void AudioDevice::OnLowLatencyCreated( | |
225 base::SharedMemoryHandle handle, | 216 base::SharedMemoryHandle handle, |
226 base::SyncSocket::Handle socket_handle, | 217 base::SyncSocket::Handle socket_handle, |
227 uint32 length) { | 218 uint32 length) { |
228 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); | 219 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); |
229 DCHECK_GE(length, buffer_size_ * sizeof(int16) * channels_); | 220 DCHECK_GE(length, buffer_size_ * sizeof(int16) * channels_); |
230 #if defined(OS_WIN) | 221 #if defined(OS_WIN) |
231 DCHECK(handle); | 222 DCHECK(handle); |
232 DCHECK(socket_handle); | 223 DCHECK(socket_handle); |
233 #else | 224 #else |
234 DCHECK_GE(handle.fd, 0); | 225 DCHECK_GE(handle.fd, 0); |
235 DCHECK_GE(socket_handle, 0); | 226 DCHECK_GE(socket_handle, 0); |
236 #endif | 227 #endif |
237 | 228 |
238 // Takes care of the case when Stop() is called before OnLowLatencyCreated(). | 229 // Takes care of the case when Stop() is called before OnStreamCreated(). |
239 if (!stream_id_) { | 230 if (!stream_id_) { |
240 base::SharedMemory::CloseHandle(handle); | 231 base::SharedMemory::CloseHandle(handle); |
241 // Close the socket handler. | 232 // Close the socket handler. |
242 base::SyncSocket socket(socket_handle); | 233 base::SyncSocket socket(socket_handle); |
243 return; | 234 return; |
244 } | 235 } |
245 | 236 |
246 shared_memory_handle_ = handle; | 237 shared_memory_handle_ = handle; |
247 memory_length_ = length; | 238 memory_length_ = length; |
248 audio_socket_.reset(new base::CancelableSyncSocket(socket_handle)); | 239 audio_socket_.reset(new base::CancelableSyncSocket(socket_handle)); |
249 | 240 |
250 audio_thread_.reset( | 241 audio_thread_.reset( |
251 new base::DelegateSimpleThread(this, "renderer_audio_thread")); | 242 new base::DelegateSimpleThread(this, "renderer_audio_thread")); |
252 audio_thread_->Start(); | 243 audio_thread_->Start(); |
253 | 244 |
254 // We handle the case where Play() and/or Pause() may have been called | 245 // We handle the case where Play() and/or Pause() may have been called |
255 // multiple times before OnLowLatencyCreated() gets called. | 246 // multiple times before OnStreamCreated() gets called. |
256 is_started_ = true; | 247 is_started_ = true; |
257 if (play_on_start_) | 248 if (play_on_start_) |
258 PlayOnIOThread(); | 249 PlayOnIOThread(); |
259 } | 250 } |
260 | 251 |
261 void AudioDevice::OnVolume(double volume) { | |
262 NOTIMPLEMENTED(); | |
263 } | |
264 | |
265 void AudioDevice::Send(IPC::Message* message) { | 252 void AudioDevice::Send(IPC::Message* message) { |
266 filter_->Send(message); | 253 filter_->Send(message); |
267 } | 254 } |
268 | 255 |
269 // Our audio thread runs here. | 256 // Our audio thread runs here. |
270 void AudioDevice::Run() { | 257 void AudioDevice::Run() { |
271 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); | 258 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); |
272 | 259 |
273 base::SharedMemory shared_memory(shared_memory_handle_, false); | 260 base::SharedMemory shared_memory(shared_memory_handle_, false); |
274 shared_memory.Map(media::TotalSharedMemorySizeInBytes(memory_length_)); | 261 shared_memory.Map(media::TotalSharedMemorySizeInBytes(memory_length_)); |
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
334 // Close the socket to terminate the main thread function in the | 321 // Close the socket to terminate the main thread function in the |
335 // audio thread. | 322 // audio thread. |
336 audio_socket_->Shutdown(); // Stops blocking Receive calls. | 323 audio_socket_->Shutdown(); // Stops blocking Receive calls. |
337 // TODO(tommi): We must not do this from the IO thread. Fix. | 324 // TODO(tommi): We must not do this from the IO thread. Fix. |
338 base::ThreadRestrictions::ScopedAllowIO allow_wait; | 325 base::ThreadRestrictions::ScopedAllowIO allow_wait; |
339 audio_thread_->Join(); | 326 audio_thread_->Join(); |
340 audio_thread_.reset(NULL); | 327 audio_thread_.reset(NULL); |
341 audio_socket_.reset(); | 328 audio_socket_.reset(); |
342 } | 329 } |
343 } | 330 } |
OLD | NEW |