Chromium Code Reviews| 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 |