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

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.
292 FireRenderCallback(reinterpret_cast<int16*>(shared_memory.memory()));
293
294 base::SyncSocket socket(socket_handle_); 291 base::SyncSocket socket(socket_handle_);
no longer working on chromium 2011/12/16 12:21:13 I am actually thinking about the opposite solution
enal1 2011/12/16 16:48:23 I believe I answered once. Pre-buffering does not
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 }
308 // Convert the number of pending bytes in the render buffer 306 // Convert the number of pending bytes in the render buffer
309 // into milliseconds. 307 // into milliseconds.
310 audio_delay_milliseconds_ = pending_data / bytes_per_ms; 308 audio_delay_milliseconds_ = pending_data / bytes_per_ms;
311 FireRenderCallback(reinterpret_cast<int16*>(shared_memory.memory())); 309 size_t num_frames = FireRenderCallback(
310 reinterpret_cast<int16*>(shared_memory.memory()));
311 // Let the host know we are done.
henrika (OOO until Aug 14) 2011/12/16 10:52:17 Shouldn't comments have an empty line above when t
enal1 2011/12/16 16:48:23 Done.
312 media::SetActualDataSizeInBytes(&shared_memory,
313 memory_length_,
314 num_frames * channels_ * sizeof(int16));
312 } 315 }
313 } 316 }
314 317
315 void AudioDevice::FireRenderCallback(int16* data) { 318 size_t AudioDevice::FireRenderCallback(int16* data) {
316 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback"); 319 TRACE_EVENT0("audio", "AudioDevice::FireRenderCallback");
317 320
321 size_t num_frames = 0;
318 if (callback_) { 322 if (callback_) {
319 // Update the audio-delay measurement then ask client to render audio. 323 // Update the audio-delay measurement then ask client to render audio.
320 callback_->Render(audio_data_, buffer_size_, audio_delay_milliseconds_); 324 num_frames = callback_->Render(audio_data_,
325 buffer_size_,
326 audio_delay_milliseconds_);
321 327
322 // Interleave, scale, and clip to int16. 328 // Interleave, scale, and clip to int16.
323 // TODO(crogers): avoid converting to integer here, and pass the data 329 // 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 330 // to the browser process as float, so we don't lose precision for
325 // audio hardware which has better than 16bit precision. 331 // audio hardware which has better than 16bit precision.
326 media::InterleaveFloatToInt16(audio_data_, 332 media::InterleaveFloatToInt16(audio_data_,
327 data, 333 data,
328 buffer_size_); 334 buffer_size_);
329 } 335 }
336 return num_frames;
330 } 337 }
331 338
332 void AudioDevice::ShutDownAudioThread() { 339 void AudioDevice::ShutDownAudioThread() {
333 // Synchronize with OnLowLatencyCreated(). 340 // Synchronize with OnLowLatencyCreated().
334 base::AutoLock auto_lock(lock_); 341 base::AutoLock auto_lock(lock_);
335 if (audio_thread_.get()) { 342 if (audio_thread_.get()) {
336 // Close the socket handler to terminate the main thread function in the 343 // Close the socket handler to terminate the main thread function in the
337 // audio thread. 344 // audio thread.
338 { 345 {
339 base::SyncSocket socket(socket_handle_); 346 base::SyncSocket socket(socket_handle_);
340 } 347 }
341 audio_thread_->Join(); 348 audio_thread_->Join();
342 audio_thread_.reset(NULL); 349 audio_thread_.reset(NULL);
343 } 350 }
344 } 351 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698