summaryrefslogtreecommitdiffstats
path: root/media/audio/audio_output_controller.cc
diff options
context:
space:
mode:
authorenal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-15 21:51:27 +0000
committerenal@chromium.org <enal@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-07-15 21:51:27 +0000
commit06e639cdc5cf9b7d3e97c7d7c57920b56b4b6e17 (patch)
tree048f6ff41defac63e23924bc88b16a6fb439ed4b /media/audio/audio_output_controller.cc
parentd466b8a0b44ef89c81fa4ede86de1b488b8ec07d (diff)
downloadchromium_src-06e639cdc5cf9b7d3e97c7d7c57920b56b4b6e17.zip
chromium_src-06e639cdc5cf9b7d3e97c7d7c57920b56b4b6e17.tar.gz
chromium_src-06e639cdc5cf9b7d3e97c7d7c57920b56b4b6e17.tar.bz2
Fix problem when 'ended' event was fired before stream really ended.
That caused impression that rewind does not work. With that change small JS program var a = new Audio("file:///home/enal/temp/click2/click2.wav"); var num_played = 0; a.addEventListener('canplaythrough', function() { a.play(); }); a.addEventListener('ended', function() { num_played ++; if (num_played < 10) { a.currentTime = 0; a.play(); } }); works correctly, you hear 10 clicks one after another, and it takes ~1.5 seconds to play all 10 sounds (one click is 146ms). Current Chrome plays only beginnings of the first 9 clicks and then entire 10th click -- 'ended' event fires too early, so rewind stops audio playback for all clicks but last one. With that fix you can easily create pool of audio objects -- on 'ended' event just add audio object to the pool. Fix consists of 3 parts: 1) For low-latency code path pass entire "audio state" object to the renderer process. That allows renderer take into account number of pending bytes in the buffer. 2) When using low-latency code path renderer not only fills the buffer with data, but also writes length of data into first word of the buffer. That allows host process to pass correct byte counts to renderer. 3) Renderer now keeps track of the earliest time playback can end based on the number of rendered bytes, and will not call 'ended' callback till that time. BUG=http://code.google.com/p/chromium/issues/detail?id=78992 http://codereview.chromium.org/7328030 Review URL: http://codereview.chromium.org/7328030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@92749 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'media/audio/audio_output_controller.cc')
-rw-r--r--media/audio/audio_output_controller.cc16
1 files changed, 9 insertions, 7 deletions
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index ec75cde..30882f4 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -5,6 +5,7 @@
#include "media/audio/audio_output_controller.h"
#include "base/message_loop.h"
+#include "media/audio/audio_buffers_state.h"
namespace media {
@@ -202,7 +203,7 @@ void AudioOutputController::DoPause() {
if (LowLatencyMode()) {
// Send a special pause mark to the low-latency audio thread.
- sync_reader_->UpdatePendingBytes(kPauseMark);
+ sync_reader_->UpdateBufferState(AudioBuffersState(kPauseMark, 0));
}
handler_->OnPaused(this);
@@ -268,13 +269,13 @@ void AudioOutputController::DoReportError(int code) {
uint32 AudioOutputController::OnMoreData(
AudioOutputStream* stream, uint8* dest,
uint32 max_size, AudioBuffersState buffers_state) {
- // If regular latency mode is used.
- if (!sync_reader_) {
- base::AutoLock auto_lock(lock_);
+ base::AutoLock auto_lock(lock_);
- // Save current buffers state.
- buffers_state_ = buffers_state;
+ // Save current buffers state.
+ buffers_state_ = buffers_state;
+ // If regular latency mode is used.
+ if (!sync_reader_) {
if (state_ != kPlaying) {
// Don't read anything. Save the number of bytes in the hardware buffer.
return 0;
@@ -288,7 +289,8 @@ uint32 AudioOutputController::OnMoreData(
// Low latency mode.
uint32 size = sync_reader_->Read(dest, max_size);
- sync_reader_->UpdatePendingBytes(buffers_state.total_bytes() + size);
+ buffers_state_.pending_bytes += size;
+ sync_reader_->UpdateBufferState(buffers_state_);
return size;
}