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

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
« no previous file with comments | « content/renderer/media/audio_device.h ('k') | content/renderer/media/audio_renderer_impl.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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.
292 FireRenderCallback(reinterpret_cast<int16*>(shared_memory.memory()));
293
294 base::SyncSocket socket(socket_handle_); 291 base::SyncSocket socket(socket_handle_);
295 292
296 int pending_data; 293 int pending_data;
297 const int samples_per_ms = static_cast<int>(sample_rate_) / 1000; 294 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; 295 const int bytes_per_ms = channels_ * (bits_per_sample_ / 8) * samples_per_ms;
299 296
300 while (sizeof(pending_data) == 297 while (sizeof(pending_data) ==
301 socket.Receive(&pending_data, sizeof(pending_data))) { 298 socket.Receive(&pending_data, sizeof(pending_data))) {
302 if (pending_data == media::AudioOutputController::kPauseMark) { 299 if (pending_data == media::AudioOutputController::kPauseMark) {
303 memset(shared_memory.memory(), 0, memory_length_); 300 memset(shared_memory.memory(), 0, memory_length_);
301 media::SetActualDataSizeInBytes(&shared_memory, memory_length_, 0);
304 continue; 302 continue;
305 } else if (pending_data < 0) { 303 } else if (pending_data < 0) {
306 break; 304 break;
307 } 305 }
306
308 // Convert the number of pending bytes in the render buffer 307 // Convert the number of pending bytes in the render buffer
309 // into milliseconds. 308 // into milliseconds.
310 audio_delay_milliseconds_ = pending_data / bytes_per_ms; 309 audio_delay_milliseconds_ = pending_data / bytes_per_ms;
311 FireRenderCallback(reinterpret_cast<int16*>(shared_memory.memory())); 310 size_t num_frames = FireRenderCallback(
311 reinterpret_cast<int16*>(shared_memory.memory()));
312
313 // Let the host know we are done.
314 media::SetActualDataSizeInBytes(&shared_memory,
315 memory_length_,
316 num_frames * channels_ * sizeof(int16));
312 } 317 }
313 } 318 }
314 319
315 void AudioDevice::FireRenderCallback(int16* data) { 320 size_t AudioDevice::FireRenderCallback(int16* data) {
316 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback"); 321 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback");
317 322
323 size_t num_frames = 0;
318 if (callback_) { 324 if (callback_) {
319 // Update the audio-delay measurement then ask client to render audio. 325 // Update the audio-delay measurement then ask client to render audio.
320 callback_->Render(audio_data_, buffer_size_, audio_delay_milliseconds_); 326 num_frames = callback_->Render(audio_data_,
327 buffer_size_,
328 audio_delay_milliseconds_);
321 329
322 // Interleave, scale, and clip to int16. 330 // Interleave, scale, and clip to int16.
323 // TODO(crogers): avoid converting to integer here, and pass the data 331 // 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 332 // to the browser process as float, so we don't lose precision for
325 // audio hardware which has better than 16bit precision. 333 // audio hardware which has better than 16bit precision.
326 media::InterleaveFloatToInt16(audio_data_, 334 media::InterleaveFloatToInt16(audio_data_,
327 data, 335 data,
328 buffer_size_); 336 buffer_size_);
329 } 337 }
338 return num_frames;
330 } 339 }
331 340
332 void AudioDevice::ShutDownAudioThread() { 341 void AudioDevice::ShutDownAudioThread() {
333 // Synchronize with OnLowLatencyCreated(). 342 // Synchronize with OnLowLatencyCreated().
334 base::AutoLock auto_lock(lock_); 343 base::AutoLock auto_lock(lock_);
335 if (audio_thread_.get()) { 344 if (audio_thread_.get()) {
336 // Close the socket handler to terminate the main thread function in the 345 // Close the socket handler to terminate the main thread function in the
337 // audio thread. 346 // audio thread.
338 { 347 {
339 base::SyncSocket socket(socket_handle_); 348 base::SyncSocket socket(socket_handle_);
340 } 349 }
341 audio_thread_->Join(); 350 audio_thread_->Join();
342 audio_thread_.reset(NULL); 351 audio_thread_.reset(NULL);
343 } 352 }
344 } 353 }
OLDNEW
« no previous file with comments | « content/renderer/media/audio_device.h ('k') | content/renderer/media/audio_renderer_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698