Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(236)

Side by Side Diff: content/renderer/media/audio_device.cc

Issue 8909006: Fix start/stop of html5 audio stream and race condition when pausing. (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 269 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 280
281 void AudioDevice::Send(IPC::Message* message) { 281 void AudioDevice::Send(IPC::Message* message) {
282 filter_->Send(message); 282 filter_->Send(message);
283 } 283 }
284 284
285 // Our audio thread runs here. 285 // Our audio thread runs here.
286 void AudioDevice::Run() { 286 void AudioDevice::Run() {
287 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio); 287 audio_thread_->SetThreadPriority(base::kThreadPriority_RealtimeAudio);
288 288
289 base::SharedMemory shared_memory(shared_memory_handle_, false); 289 base::SharedMemory shared_memory(shared_memory_handle_, false);
290 shared_memory.Map(memory_length_); 290 shared_memory.Map(media::TotalSharedMemorySizeInBytes(memory_length_));
291 // Allow the client to pre-populate the buffer. 291 // Allow the client to pre-populate the buffer.
292 FireRenderCallback(reinterpret_cast<int16*>(shared_memory.memory())); 292 // If it cannot it just returns zero.
293 size_t num_frames = FireRenderCallback(
294 reinterpret_cast<int16*>(shared_memory.memory()));
295 if (num_frames == 0)
296 media::SetUnknownDataSize(&shared_memory, memory_length_);
297 else
298 media::SetActualDataSizeInBytes(&shared_memory,
299 memory_length_,
300 num_frames * channels_ * sizeof(int16));
293 301
294 base::SyncSocket socket(socket_handle_); 302 base::SyncSocket socket(socket_handle_);
295 303
296 int pending_data; 304 int pending_data;
297 const int samples_per_ms = static_cast<int>(sample_rate_) / 1000; 305 const int samples_per_ms = static_cast<int>(sample_rate_) / 1000;
298 const int bytes_per_ms = channels_ * (bits_per_sample_ / 8) * samples_per_ms; 306 const int bytes_per_ms = channels_ * (bits_per_sample_ / 8) * samples_per_ms;
299 307
300 while (sizeof(pending_data) == 308 while (sizeof(pending_data) ==
301 socket.Receive(&pending_data, sizeof(pending_data))) { 309 socket.Receive(&pending_data, sizeof(pending_data))) {
302 if (pending_data == media::AudioOutputController::kPauseMark) { 310 if (pending_data == media::AudioOutputController::kPauseMark) {
303 memset(shared_memory.memory(), 0, memory_length_); 311 memset(shared_memory.memory(), 0, memory_length_);
312 media::SetActualDataSizeInBytes(&shared_memory, memory_length_, 0);
304 continue; 313 continue;
305 } else if (pending_data < 0) { 314 } else if (pending_data < 0) {
306 break; 315 break;
307 } 316 }
308 // Convert the number of pending bytes in the render buffer 317 // Convert the number of pending bytes in the render buffer
309 // into milliseconds. 318 // into milliseconds.
310 audio_delay_milliseconds_ = pending_data / bytes_per_ms; 319 audio_delay_milliseconds_ = pending_data / bytes_per_ms;
311 FireRenderCallback(reinterpret_cast<int16*>(shared_memory.memory())); 320 num_frames = FireRenderCallback(
321 reinterpret_cast<int16*>(shared_memory.memory()));
322 // Let the host know we are done.
323 media::SetActualDataSizeInBytes(&shared_memory,
324 memory_length_,
325 num_frames * channels_ * sizeof(int16));
312 } 326 }
313 } 327 }
314 328
315 void AudioDevice::FireRenderCallback(int16* data) { 329 size_t AudioDevice::FireRenderCallback(int16* data) {
316 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback"); 330 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback");
317 331
332 size_t num_frames = 0;
318 if (callback_) { 333 if (callback_) {
319 // Update the audio-delay measurement then ask client to render audio. 334 // Update the audio-delay measurement then ask client to render audio.
320 callback_->Render(audio_data_, buffer_size_, audio_delay_milliseconds_); 335 num_frames = callback_->Render(audio_data_,
336 buffer_size_,
337 audio_delay_milliseconds_);
321 338
322 // Interleave, scale, and clip to int16. 339 // Interleave, scale, and clip to int16.
323 // TODO(crogers): avoid converting to integer here, and pass the data 340 // TODO(crogers): avoid converting to integer here, and pass the data
324 // to the browser process as float, so we don't lose precision for 341 // to the browser process as float, so we don't lose precision for
325 // audio hardware which has better than 16bit precision. 342 // audio hardware which has better than 16bit precision.
326 media::InterleaveFloatToInt16(audio_data_, 343 media::InterleaveFloatToInt16(audio_data_,
327 data, 344 data,
328 buffer_size_); 345 buffer_size_);
329 } 346 }
347 return num_frames;
330 } 348 }
331 349
332 void AudioDevice::ShutDownAudioThread() { 350 void AudioDevice::ShutDownAudioThread() {
333 // Synchronize with OnLowLatencyCreated(). 351 // Synchronize with OnLowLatencyCreated().
334 base::AutoLock auto_lock(lock_); 352 base::AutoLock auto_lock(lock_);
335 if (audio_thread_.get()) { 353 if (audio_thread_.get()) {
336 // Close the socket handler to terminate the main thread function in the 354 // Close the socket handler to terminate the main thread function in the
337 // audio thread. 355 // audio thread.
338 { 356 {
339 base::SyncSocket socket(socket_handle_); 357 base::SyncSocket socket(socket_handle_);
340 } 358 }
341 audio_thread_->Join(); 359 audio_thread_->Join();
342 audio_thread_.reset(NULL); 360 audio_thread_.reset(NULL);
343 } 361 }
344 } 362 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698