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/time.h" | 10 #include "base/time.h" |
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
236 // Takes care of the case when Stop() is called before OnLowLatencyCreated(). | 236 // Takes care of the case when Stop() is called before OnLowLatencyCreated(). |
237 if (!stream_id_) { | 237 if (!stream_id_) { |
238 base::SharedMemory::CloseHandle(handle); | 238 base::SharedMemory::CloseHandle(handle); |
239 // Close the socket handler. | 239 // Close the socket handler. |
240 base::SyncSocket socket(socket_handle); | 240 base::SyncSocket socket(socket_handle); |
241 return; | 241 return; |
242 } | 242 } |
243 | 243 |
244 shared_memory_handle_ = handle; | 244 shared_memory_handle_ = handle; |
245 memory_length_ = length; | 245 memory_length_ = length; |
246 audio_socket_ = new AudioSocket(socket_handle); | 246 audio_socket_.reset(new base::CancelableSyncSocket(socket_handle)); |
247 | 247 |
248 audio_thread_.reset( | 248 audio_thread_.reset( |
249 new base::DelegateSimpleThread(this, "renderer_audio_thread")); | 249 new base::DelegateSimpleThread(this, "renderer_audio_thread")); |
250 audio_thread_->Start(); | 250 audio_thread_->Start(); |
251 | 251 |
252 // We handle the case where Play() and/or Pause() may have been called | 252 // We handle the case where Play() and/or Pause() may have been called |
253 // multiple times before OnLowLatencyCreated() gets called. | 253 // multiple times before OnLowLatencyCreated() gets called. |
254 is_started_ = true; | 254 is_started_ = true; |
255 if (play_on_start_) | 255 if (play_on_start_) |
256 PlayOnIOThread(); | 256 PlayOnIOThread(); |
257 } | 257 } |
258 | 258 |
259 void AudioDevice::OnVolume(double volume) { | 259 void AudioDevice::OnVolume(double volume) { |
260 NOTIMPLEMENTED(); | 260 NOTIMPLEMENTED(); |
261 } | 261 } |
262 | 262 |
263 void AudioDevice::Send(IPC::Message* message) { | 263 void AudioDevice::Send(IPC::Message* message) { |
264 filter_->Send(message); | 264 filter_->Send(message); |
265 } | 265 } |
266 | 266 |
267 // Our audio thread runs here. | 267 // Our audio thread runs here. |
268 void AudioDevice::Run() { | 268 void AudioDevice::Run() { |
269 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); | 269 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); |
270 | 270 |
271 base::SharedMemory shared_memory(shared_memory_handle_, false); | 271 base::SharedMemory shared_memory(shared_memory_handle_, false); |
272 shared_memory.Map(media::TotalSharedMemorySizeInBytes(memory_length_)); | 272 shared_memory.Map(media::TotalSharedMemorySizeInBytes(memory_length_)); |
273 scoped_refptr<AudioSocket> audio_socket(audio_socket_); | 273 base::CancelableSyncSocket* audio_socket = audio_socket_.get(); |
274 | 274 |
275 int pending_data; | 275 int pending_data; |
276 const int samples_per_ms = static_cast<int>(sample_rate_) / 1000; | 276 const int samples_per_ms = static_cast<int>(sample_rate_) / 1000; |
277 const int bytes_per_ms = channels_ * (bits_per_sample_ / 8) * samples_per_ms; | 277 const int bytes_per_ms = channels_ * (bits_per_sample_ / 8) * samples_per_ms; |
278 | 278 |
279 while (sizeof(pending_data) == | 279 size_t bytes_read = 0U; |
280 audio_socket->socket()->Receive(&pending_data, sizeof(pending_data))) { | 280 while (true) { |
| 281 bytes_read = audio_socket->Receive(&pending_data, sizeof(pending_data)); |
| 282 if (bytes_read != sizeof(pending_data)) |
| 283 break; |
| 284 |
281 if (pending_data == media::AudioOutputController::kPauseMark) { | 285 if (pending_data == media::AudioOutputController::kPauseMark) { |
282 memset(shared_memory.memory(), 0, memory_length_); | 286 memset(shared_memory.memory(), 0, memory_length_); |
283 media::SetActualDataSizeInBytes(&shared_memory, memory_length_, 0); | 287 media::SetActualDataSizeInBytes(&shared_memory, memory_length_, 0); |
284 continue; | 288 continue; |
285 } else if (pending_data < 0) { | 289 } else if (pending_data < 0) { |
286 break; | 290 break; |
287 } | 291 } |
288 | 292 |
289 // Convert the number of pending bytes in the render buffer | 293 // Convert the number of pending bytes in the render buffer |
290 // into milliseconds. | 294 // into milliseconds. |
291 audio_delay_milliseconds_ = pending_data / bytes_per_ms; | 295 audio_delay_milliseconds_ = pending_data / bytes_per_ms; |
292 size_t num_frames = FireRenderCallback( | 296 size_t num_frames = FireRenderCallback( |
293 reinterpret_cast<int16*>(shared_memory.memory())); | 297 reinterpret_cast<int16*>(shared_memory.memory())); |
294 | 298 |
295 // Let the host know we are done. | 299 // Let the host know we are done. |
296 media::SetActualDataSizeInBytes(&shared_memory, | 300 media::SetActualDataSizeInBytes(&shared_memory, |
297 memory_length_, | 301 memory_length_, |
298 num_frames * channels_ * sizeof(int16)); | 302 num_frames * channels_ * sizeof(int16)); |
299 } | 303 } |
300 audio_socket->Close(); | 304 DCHECK_EQ(bytes_read, 0U); |
301 } | 305 } |
302 | 306 |
303 size_t AudioDevice::FireRenderCallback(int16* data) { | 307 size_t AudioDevice::FireRenderCallback(int16* data) { |
304 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback"); | 308 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback"); |
305 | 309 |
306 size_t num_frames = 0; | 310 size_t num_frames = 0; |
307 if (callback_) { | 311 if (callback_) { |
308 // Update the audio-delay measurement then ask client to render audio. | 312 // Update the audio-delay measurement then ask client to render audio. |
309 num_frames = callback_->Render(audio_data_, | 313 num_frames = callback_->Render(audio_data_, |
310 buffer_size_, | 314 buffer_size_, |
311 audio_delay_milliseconds_); | 315 audio_delay_milliseconds_); |
312 | 316 |
313 // Interleave, scale, and clip to int16. | 317 // Interleave, scale, and clip to int16. |
314 // TODO(crogers): avoid converting to integer here, and pass the data | 318 // TODO(crogers): avoid converting to integer here, and pass the data |
315 // to the browser process as float, so we don't lose precision for | 319 // to the browser process as float, so we don't lose precision for |
316 // audio hardware which has better than 16bit precision. | 320 // audio hardware which has better than 16bit precision. |
317 media::InterleaveFloatToInt16(audio_data_, | 321 media::InterleaveFloatToInt16(audio_data_, |
318 data, | 322 data, |
319 buffer_size_); | 323 buffer_size_); |
320 } | 324 } |
321 return num_frames; | 325 return num_frames; |
322 } | 326 } |
323 | 327 |
324 void AudioDevice::ShutDownAudioThread() { | 328 void AudioDevice::ShutDownAudioThread() { |
325 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); | 329 DCHECK_EQ(MessageLoop::current(), ChildProcess::current()->io_message_loop()); |
326 | 330 |
327 if (audio_thread_.get()) { | 331 if (audio_thread_.get()) { |
328 // Close the socket to terminate the main thread function in the | 332 // Close the socket to terminate the main thread function in the |
329 // audio thread. | 333 // audio thread. |
330 audio_socket_->Close(); | 334 audio_socket_->Shutdown(); // Stops blocking Receive calls. |
331 audio_socket_ = NULL; | |
332 audio_thread_->Join(); | 335 audio_thread_->Join(); |
333 audio_thread_.reset(NULL); | 336 audio_thread_.reset(NULL); |
| 337 audio_socket_.reset(); |
334 } | 338 } |
335 } | 339 } |
OLD | NEW |