summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authordalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-05 06:12:36 +0000
committerdalecurtis@chromium.org <dalecurtis@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-06-05 06:12:36 +0000
commit1b09add967241eb1f56b1f368ee401bf8f79c165 (patch)
tree27d15f5261cc29dd677c9b152f167d31d388292b
parentd385ba9a84e6e0c31604066078048fbd0e6bb89f (diff)
downloadchromium_src-1b09add967241eb1f56b1f368ee401bf8f79c165.zip
chromium_src-1b09add967241eb1f56b1f368ee401bf8f79c165.tar.gz
chromium_src-1b09add967241eb1f56b1f368ee401bf8f79c165.tar.bz2
Privitize WaitTillDataReady() and DataReady().
There's no reason for these to be called all over the code base when we know the limited circumstances under which they must be called. Making these private allows for a considerable cleanup of code. The one sketchy part about this CL is removing PollAndStartIfDataReady() for OSX. I believe stream startup times are long enough that data will always be ready though. If this is not the case and our OSX stats for DataReady() plummet, we can find a simpler solution then polling. This change also fixes inaccuracy with the UMA histogram since previously we were reporting DataReady() after WaitTilDataReady() had already been called. BUG=none TEST=audio plays w/o glitching on mac, win, linux. Review URL: https://chromiumcodereview.appspot.com/16103007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@204172 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--content/browser/renderer_host/media/audio_sync_reader.cc32
-rw-r--r--content/browser/renderer_host/media/audio_sync_reader.h11
-rw-r--r--media/audio/audio_io.h4
-rw-r--r--media/audio/audio_low_latency_input_output_unittest.cc1
-rw-r--r--media/audio/audio_output_controller.cc91
-rw-r--r--media/audio/audio_output_controller.h47
-rw-r--r--media/audio/audio_output_controller_unittest.cc12
-rw-r--r--media/audio/audio_output_resampler.cc7
-rw-r--r--media/audio/linux/alsa_output.cc4
-rw-r--r--media/audio/pulse/pulse_input.cc3
-rw-r--r--media/audio/pulse/pulse_output.cc1
-rw-r--r--media/audio/pulse/pulse_unified.cc1
-rw-r--r--media/audio/virtual_audio_output_stream.cc4
-rw-r--r--media/audio/win/waveout_output_win.cc11
14 files changed, 73 insertions, 156 deletions
diff --git a/content/browser/renderer_host/media/audio_sync_reader.cc b/content/browser/renderer_host/media/audio_sync_reader.cc
index 9ebf5ed..39fc80d1 100644
--- a/content/browser/renderer_host/media/audio_sync_reader.cc
+++ b/content/browser/renderer_host/media/audio_sync_reader.cc
@@ -68,11 +68,15 @@ void AudioSyncReader::UpdatePendingBytes(uint32 bytes) {
}
}
-int AudioSyncReader::Read(AudioBus* source, AudioBus* dest) {
+int AudioSyncReader::Read(bool block, const AudioBus* source, AudioBus* dest) {
++renderer_callback_count_;
- if (!DataReady())
+ if (!DataReady()) {
++renderer_missed_callback_count_;
+ if (block)
+ WaitTillDataReady();
+ }
+
// Copy optional synchronized live audio input for consumption by renderer
// process.
if (source && input_bus_) {
@@ -162,4 +166,28 @@ bool AudioSyncReader::PrepareForeignSocketHandle(
}
#endif
+void AudioSyncReader::WaitTillDataReady() {
+ base::TimeTicks start = base::TimeTicks::Now();
+ const base::TimeDelta kMaxWait = base::TimeDelta::FromMilliseconds(20);
+#if defined(OS_WIN)
+ // Sleep(0) on Windows lets the other threads run.
+ const base::TimeDelta kSleep = base::TimeDelta::FromMilliseconds(0);
+#else
+ // We want to sleep for a bit here, as otherwise a backgrounded renderer won't
+ // get enough cpu to send the data and the high priority thread in the browser
+ // will use up a core causing even more skips.
+ const base::TimeDelta kSleep = base::TimeDelta::FromMilliseconds(2);
+#endif
+ base::TimeDelta time_since_start;
+ do {
+ base::PlatformThread::Sleep(kSleep);
+ time_since_start = base::TimeTicks::Now() - start;
+ } while (!DataReady() && time_since_start < kMaxWait);
+ UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioOutputControllerDataNotReady",
+ time_since_start,
+ base::TimeDelta::FromMilliseconds(1),
+ base::TimeDelta::FromMilliseconds(1000),
+ 50);
+}
+
} // namespace content
diff --git a/content/browser/renderer_host/media/audio_sync_reader.h b/content/browser/renderer_host/media/audio_sync_reader.h
index 1f07b20..80f7b62 100644
--- a/content/browser/renderer_host/media/audio_sync_reader.h
+++ b/content/browser/renderer_host/media/audio_sync_reader.h
@@ -33,9 +33,10 @@ class AudioSyncReader : public media::AudioOutputController::SyncReader {
// media::AudioOutputController::SyncReader implementations.
virtual void UpdatePendingBytes(uint32 bytes) OVERRIDE;
- virtual int Read(media::AudioBus* source, media::AudioBus* dest) OVERRIDE;
+ virtual int Read(bool block,
+ const media::AudioBus* source,
+ media::AudioBus* dest) OVERRIDE;
virtual void Close() OVERRIDE;
- virtual bool DataReady() OVERRIDE;
bool Init();
bool PrepareForeignSocketHandle(base::ProcessHandle process_handle,
@@ -46,6 +47,12 @@ class AudioSyncReader : public media::AudioOutputController::SyncReader {
#endif
private:
+ // Indicates whether the renderer has data available for reading.
+ bool DataReady();
+
+ // Blocks until DataReady() is true or a timeout expires.
+ void WaitTillDataReady();
+
base::SharedMemory* shared_memory_;
// Number of input channels for synchronized I/O.
diff --git a/media/audio/audio_io.h b/media/audio/audio_io.h
index 0f3f673..473af0d 100644
--- a/media/audio/audio_io.h
+++ b/media/audio/audio_io.h
@@ -73,10 +73,6 @@ class MEDIA_EXPORT AudioOutputStream {
// playback will not continue.
virtual void OnError(AudioOutputStream* stream) = 0;
- // Will block until the client has written its audio data or 1.5 seconds
- // have elapsed.
- virtual void WaitTillDataReady() {}
-
protected:
virtual ~AudioSourceCallback() {}
};
diff --git a/media/audio/audio_low_latency_input_output_unittest.cc b/media/audio/audio_low_latency_input_output_unittest.cc
index 4dd22ab..f4aeab4 100644
--- a/media/audio/audio_low_latency_input_output_unittest.cc
+++ b/media/audio/audio_low_latency_input_output_unittest.cc
@@ -258,7 +258,6 @@ class FullDuplexAudioSinkSource
}
virtual void OnError(AudioOutputStream* stream) OVERRIDE {}
- virtual void WaitTillDataReady() OVERRIDE {}
protected:
// Converts from bytes to milliseconds taking the sample rate and size
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index 8e33c7f..aea6440 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -52,8 +52,7 @@ AudioOutputController::AudioOutputController(AudioManager* audio_manager,
num_allowed_io_(0),
sync_reader_(sync_reader),
message_loop_(audio_manager->GetMessageLoop()),
- number_polling_attempts_left_(0),
- weak_this_(this) {
+ number_polling_attempts_left_(0) {
DCHECK(audio_manager);
DCHECK(handler_);
DCHECK(sync_reader_);
@@ -149,52 +148,16 @@ void AudioOutputController::DoCreate(bool is_for_device_change) {
void AudioOutputController::DoPlay() {
DCHECK(message_loop_->BelongsToCurrentThread());
+ SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime");
// We can start from created or paused state.
if (state_ != kCreated && state_ != kPaused)
return;
- state_ = kStarting;
-
// Ask for first packet.
sync_reader_->UpdatePendingBytes(0);
- // Cannot start stream immediately, should give renderer some time
- // to deliver data.
- // TODO(vrk): The polling here and in WaitTillDataReady() is pretty clunky.
- // Refine the API such that polling is no longer needed. (crbug.com/112196)
- number_polling_attempts_left_ = kPollNumAttempts;
- DCHECK(!weak_this_.HasWeakPtrs());
- message_loop_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&AudioOutputController::PollAndStartIfDataReady,
- weak_this_.GetWeakPtr()),
- TimeDelta::FromMilliseconds(kPollPauseInMilliseconds));
-}
-
-void AudioOutputController::PollAndStartIfDataReady() {
- DCHECK(message_loop_->BelongsToCurrentThread());
- SCOPED_UMA_HISTOGRAM_TIMER("Media.AudioOutputController.PlayTime");
-
- DCHECK_EQ(kStarting, state_);
-
- // If we are ready to start the stream, start it.
- if (--number_polling_attempts_left_ == 0 ||
- sync_reader_->DataReady()) {
- StartStream();
- } else {
- message_loop_->PostDelayedTask(
- FROM_HERE,
- base::Bind(&AudioOutputController::PollAndStartIfDataReady,
- weak_this_.GetWeakPtr()),
- TimeDelta::FromMilliseconds(kPollPauseInMilliseconds));
- }
-}
-
-void AudioOutputController::StartStream() {
- DCHECK(message_loop_->BelongsToCurrentThread());
state_ = kPlaying;
-
silence_detector_.reset(new AudioSilenceDetector(
params_.sample_rate(),
TimeDelta::FromMilliseconds(kQuestionableSilencePeriodMillis),
@@ -214,11 +177,7 @@ void AudioOutputController::StartStream() {
void AudioOutputController::StopStream() {
DCHECK(message_loop_->BelongsToCurrentThread());
- if (state_ == kStarting) {
- // Cancel in-progress polling start.
- weak_this_.InvalidateWeakPtrs();
- state_ = kPaused;
- } else if (state_ == kPlaying) {
+ if (state_ == kPlaying) {
stream_->Stop();
DisallowEntryToOnMoreIOData();
silence_detector_->Stop(true);
@@ -262,7 +221,6 @@ void AudioOutputController::DoSetVolume(double volume) {
switch (state_) {
case kCreated:
- case kStarting:
case kPlaying:
case kPaused:
stream_->SetVolume(volume_);
@@ -291,15 +249,23 @@ int AudioOutputController::OnMoreIOData(AudioBus* source,
// The OS level audio APIs on Linux and Windows all have problems requesting
// data on a fixed interval. Sometimes they will issue calls back to back
- // which can cause glitching, so wait until the renderer is ready for Read().
+ // which can cause glitching, so wait until the renderer is ready.
+ //
+ // We also need to wait when diverting since the virtual stream will call this
+ // multiple times without waiting.
+ //
+ // NEVER wait on OSX unless a virtual stream is connected, otherwise we can
+ // end up hanging the entire OS.
//
// See many bugs for context behind this decision: http://crbug.com/170498,
// http://crbug.com/171651, http://crbug.com/174985, and more.
#if defined(OS_WIN) || defined(OS_LINUX)
- WaitTillDataReady();
+ const bool kShouldBlock = true;
+#else
+ const bool kShouldBlock = diverting_to_stream_ != NULL;
#endif
- const int frames = sync_reader_->Read(source, dest);
+ const int frames = sync_reader_->Read(kShouldBlock, source, dest);
DCHECK_LE(0, frames);
sync_reader_->UpdatePendingBytes(
buffers_state.total_bytes() + frames * params_.GetBytesPerFrame());
@@ -310,34 +276,6 @@ int AudioOutputController::OnMoreIOData(AudioBus* source,
return frames;
}
-void AudioOutputController::WaitTillDataReady() {
- // Most of the time the data is ready already.
- if (sync_reader_->DataReady())
- return;
-
- base::TimeTicks start = base::TimeTicks::Now();
- const base::TimeDelta kMaxWait = base::TimeDelta::FromMilliseconds(20);
-#if defined(OS_WIN)
- // Sleep(0) on windows lets the other threads run.
- const base::TimeDelta kSleep = base::TimeDelta::FromMilliseconds(0);
-#else
- // We want to sleep for a bit here, as otherwise a backgrounded renderer won't
- // get enough cpu to send the data and the high priority thread in the browser
- // will use up a core causing even more skips.
- const base::TimeDelta kSleep = base::TimeDelta::FromMilliseconds(2);
-#endif
- base::TimeDelta time_since_start;
- do {
- base::PlatformThread::Sleep(kSleep);
- time_since_start = base::TimeTicks::Now() - start;
- } while (!sync_reader_->DataReady() && (time_since_start < kMaxWait));
- UMA_HISTOGRAM_CUSTOM_TIMES("Media.AudioOutputControllerDataNotReady",
- time_since_start,
- base::TimeDelta::FromMilliseconds(1),
- base::TimeDelta::FromMilliseconds(1000),
- 50);
-}
-
void AudioOutputController::OnError(AudioOutputStream* stream) {
// Handle error on the audio controller thread.
message_loop_->PostTask(FROM_HERE, base::Bind(
@@ -381,7 +319,6 @@ void AudioOutputController::OnDeviceChange() {
// Get us back to the original state or an equivalent state.
switch (original_state) {
- case kStarting:
case kPlaying:
DoPlay();
return;
diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h
index 1e56633..93acc27 100644
--- a/media/audio/audio_output_controller.h
+++ b/media/audio/audio_output_controller.h
@@ -9,9 +9,7 @@
#include "base/callback.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
-#include "base/memory/weak_ptr.h"
#include "base/timer.h"
-#include "media/audio/audio_buffers_state.h"
#include "media/audio/audio_io.h"
#include "media/audio/audio_manager.h"
#include "media/audio/audio_source_diverter.h"
@@ -28,14 +26,14 @@
//
// Here is a state transition diagram for the AudioOutputController:
//
-// *[ Empty ] --> [ Created ] --> [ Starting ] --> [ Playing ] --.
-// | | | ^ | |
-// | | | | | |
-// | | | | v |
-// | | | `--------- [ Paused ] |
-// | | | | |
-// | v v | |
-// `-----------> [ Closed ] <-------------------------'
+// *[ Empty ] --> [ Created ] --> [ Playing ] -------.
+// | | | ^ |
+// | | | | |
+// | | | | v
+// | | | `----- [ Paused ]
+// | | | |
+// | v v |
+// `-----------> [ Closed ] <-----------'
//
// * Initial state
//
@@ -51,9 +49,6 @@
// AudioSourceCallback interface. AudioOutputController uses the SyncReader
// passed to it via construction to synchronously fulfill this read request.
//
-// Since AudioOutputController uses AudioManager's message loop the controller
-// uses WeakPtr to allow safe cancellation of pending tasks.
-//
namespace media {
@@ -93,16 +88,14 @@ class MEDIA_EXPORT AudioOutputController
// prepare more data and perform synchronization.
virtual void UpdatePendingBytes(uint32 bytes) = 0;
- // Attempt to completely fill |dest|, return the actual number of
- // frames that could be read.
- // |source| may optionally be provided for input data.
- virtual int Read(AudioBus* source, AudioBus* dest) = 0;
+ // Attempt to completely fill |dest|, return the actual number of frames
+ // that could be read. |source| may optionally be provided for input data.
+ // If |block| is specified, the Read() will block until data is available
+ // or a timeout is reached.
+ virtual int Read(bool block, const AudioBus* source, AudioBus* dest) = 0;
// Close this synchronous reader.
virtual void Close() = 0;
-
- // Check if data is ready.
- virtual bool DataReady() = 0;
};
// Factory method for creating an AudioOutputController.
@@ -142,9 +135,6 @@ class MEDIA_EXPORT AudioOutputController
AudioBus* dest,
AudioBuffersState buffers_state) OVERRIDE;
virtual void OnError(AudioOutputStream* stream) OVERRIDE;
- // Deprecated: Currently only used for starting audio playback and for audio
- // mirroring.
- virtual void WaitTillDataReady() OVERRIDE;
// AudioDeviceListener implementation. When called AudioOutputController will
// shutdown the existing |stream_|, transition to the kRecreating state,
@@ -162,7 +152,6 @@ class MEDIA_EXPORT AudioOutputController
enum State {
kEmpty,
kCreated,
- kStarting,
kPlaying,
kPaused,
kClosed,
@@ -185,7 +174,6 @@ class MEDIA_EXPORT AudioOutputController
// The following methods are executed on the audio manager thread.
void DoCreate(bool is_for_device_change);
void DoPlay();
- void PollAndStartIfDataReady();
void DoPause();
void DoClose();
void DoSetVolume(double volume);
@@ -197,8 +185,7 @@ class MEDIA_EXPORT AudioOutputController
// silence and call EventHandler::OnAudible() when state changes occur.
void MaybeInvokeAudibleCallback();
- // Helper methods that start/stop physical stream.
- void StartStream();
+ // Helper method that stops the physical stream.
void StopStream();
// Helper method that stops, closes, and NULLs |*stream_|.
@@ -216,8 +203,6 @@ class MEDIA_EXPORT AudioOutputController
// Used by the unified IO to open the correct input device.
std::string input_device_id_;
- // Note: It's important to invalidate the weak pointers whenever stream_ is
- // changed. See comment for weak_this_.
AudioOutputStream* stream_;
// When non-NULL, audio is being diverted to this stream.
@@ -248,10 +233,6 @@ class MEDIA_EXPORT AudioOutputController
// Number of times left.
int number_polling_attempts_left_;
- // Used to auto-cancel the delayed tasks that are created to poll for data
- // (when starting-up a stream).
- base::WeakPtrFactory<AudioOutputController> weak_this_;
-
// Scans audio samples from OnMoreIOData() as input and causes
// EventHandler::OnAudbile() to be called whenever a transition to a period of
// silence or non-silence is detected.
diff --git a/media/audio/audio_output_controller_unittest.cc b/media/audio/audio_output_controller_unittest.cc
index c2630b0..ab4f652 100644
--- a/media/audio/audio_output_controller_unittest.cc
+++ b/media/audio/audio_output_controller_unittest.cc
@@ -55,9 +55,8 @@ class MockAudioOutputControllerSyncReader
MockAudioOutputControllerSyncReader() {}
MOCK_METHOD1(UpdatePendingBytes, void(uint32 bytes));
- MOCK_METHOD2(Read, int(AudioBus* source, AudioBus* dest));
+ MOCK_METHOD3(Read, int(bool block, const AudioBus* source, AudioBus* dest));
MOCK_METHOD0(Close, void());
- MOCK_METHOD0(DataReady, bool());
private:
DISALLOW_COPY_AND_ASSIGN(MockAudioOutputControllerSyncReader);
@@ -86,10 +85,10 @@ ACTION_P(SignalEvent, event) {
static const float kBufferNonZeroData = 1.0f;
ACTION(PopulateBuffer) {
- arg1->Zero();
+ arg2->Zero();
// Note: To confirm the buffer will be populated in these tests, it's
// sufficient that only the first float in channel 0 is set to the value.
- arg1->channel(0)[0] = kBufferNonZeroData;
+ arg2->channel(0)[0] = kBufferNonZeroData;
}
class AudioOutputControllerTest : public testing::Test {
@@ -142,13 +141,10 @@ class AudioOutputControllerTest : public testing::Test {
// sent from the render process.
EXPECT_CALL(mock_sync_reader_, UpdatePendingBytes(_))
.Times(AtLeast(1));
- EXPECT_CALL(mock_sync_reader_, Read(_, _))
+ EXPECT_CALL(mock_sync_reader_, Read(_, _, _))
.WillRepeatedly(DoAll(PopulateBuffer(),
SignalEvent(&read_event_),
Return(params_.frames_per_buffer())));
- EXPECT_CALL(mock_sync_reader_, DataReady())
- .WillRepeatedly(Return(true));
-
controller_->Play();
}
diff --git a/media/audio/audio_output_resampler.cc b/media/audio/audio_output_resampler.cc
index ea1848e..ad12d27 100644
--- a/media/audio/audio_output_resampler.cc
+++ b/media/audio/audio_output_resampler.cc
@@ -36,7 +36,6 @@ class OnMoreDataConverter
AudioBus* dest,
AudioBuffersState buffers_state) OVERRIDE;
virtual void OnError(AudioOutputStream* stream) OVERRIDE;
- virtual void WaitTillDataReady() OVERRIDE;
// Sets |source_callback_|. If this is not a new object, then Stop() must be
// called before Start().
@@ -393,10 +392,4 @@ void OnMoreDataConverter::OnError(AudioOutputStream* stream) {
source_callback_->OnError(stream);
}
-void OnMoreDataConverter::WaitTillDataReady() {
- base::AutoLock auto_lock(source_lock_);
- if (source_callback_)
- source_callback_->WaitTillDataReady();
-}
-
} // namespace media
diff --git a/media/audio/linux/alsa_output.cc b/media/audio/linux/alsa_output.cc
index 3c2520e..9058555 100644
--- a/media/audio/linux/alsa_output.cc
+++ b/media/audio/linux/alsa_output.cc
@@ -744,10 +744,8 @@ int AlsaPcmOutputStream::RunDataCallback(AudioBus* audio_bus,
AudioBuffersState buffers_state) {
TRACE_EVENT0("audio", "AlsaPcmOutputStream::RunDataCallback");
- if (source_callback_) {
- source_callback_->WaitTillDataReady();
+ if (source_callback_)
return source_callback_->OnMoreData(audio_bus, buffers_state);
- }
return 0;
}
diff --git a/media/audio/pulse/pulse_input.cc b/media/audio/pulse/pulse_input.cc
index c365c47..cc62085 100644
--- a/media/audio/pulse/pulse_input.cc
+++ b/media/audio/pulse/pulse_input.cc
@@ -278,8 +278,7 @@ void PulseAudioInputStream::ReadData() {
if (buffer_->forward_bytes() < packet_size)
break;
- // TODO(xians): improve the code by implementing a WaitTillDataReady on the
- // input side.
+ // TODO(xians): Remove once PPAPI is using circular buffers.
DVLOG(1) << "OnData is being called consecutively, sleep 5ms to "
<< "wait until render consumes the data";
base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(5));
diff --git a/media/audio/pulse/pulse_output.cc b/media/audio/pulse/pulse_output.cc
index 1734954..99ede3b 100644
--- a/media/audio/pulse/pulse_output.cc
+++ b/media/audio/pulse/pulse_output.cc
@@ -129,7 +129,6 @@ void PulseAudioOutputStream::FulfillWriteRequest(size_t requested_bytes) {
uint32 hardware_delay = pulse::GetHardwareLatencyInBytes(
pa_stream_, params_.sample_rate(),
params_.GetBytesPerFrame());
- source_callback_->WaitTillDataReady();
frames_filled = source_callback_->OnMoreData(
audio_bus_.get(), AudioBuffersState(0, hardware_delay));
}
diff --git a/media/audio/pulse/pulse_unified.cc b/media/audio/pulse/pulse_unified.cc
index ee14341..cfa55a2 100644
--- a/media/audio/pulse/pulse_unified.cc
+++ b/media/audio/pulse/pulse_unified.cc
@@ -157,7 +157,6 @@ void PulseAudioUnifiedStream::WriteData(size_t requested_bytes) {
uint32 hardware_delay = pulse::GetHardwareLatencyInBytes(
output_stream_, params_.sample_rate(),
params_.GetBytesPerFrame());
- source_callback_->WaitTillDataReady();
fifo_->Read(input_data_buffer_.get(), requested_bytes);
input_bus_->FromInterleaved(
input_data_buffer_.get(), params_.frames_per_buffer(), 2);
diff --git a/media/audio/virtual_audio_output_stream.cc b/media/audio/virtual_audio_output_stream.cc
index 005fbc2..254a70a 100644
--- a/media/audio/virtual_audio_output_stream.cc
+++ b/media/audio/virtual_audio_output_stream.cc
@@ -74,10 +74,6 @@ double VirtualAudioOutputStream::ProvideInput(AudioBus* audio_bus,
DCHECK(message_loop_->BelongsToCurrentThread());
DCHECK(callback_);
- // A VirtualAudioInputStream with a larger buffer size may be calling this
- // multiple times without waiting, so we need to block and ensure the data is
- // ready to prevent glitching.
- callback_->WaitTillDataReady();
const int frames = callback_->OnMoreData(audio_bus, AudioBuffersState());
if (frames < audio_bus->frames())
audio_bus->ZeroFramesPartial(frames, audio_bus->frames() - frames);
diff --git a/media/audio/win/waveout_output_win.cc b/media/audio/win/waveout_output_win.cc
index 9b03c31..47d4fa6 100644
--- a/media/audio/win/waveout_output_win.cc
+++ b/media/audio/win/waveout_output_win.cc
@@ -204,10 +204,6 @@ void PCMWaveOutAudioOutputStream::Start(AudioSourceCallback* callback) {
pending_bytes_ = 0;
for (int ix = 0; ix != num_buffers_; ++ix) {
WAVEHDR* buffer = GetBuffer(ix);
- // Caller waits for 1st packet to become available, but not for others,
- // so we wait for them here.
- if (ix != 0)
- callback_->WaitTillDataReady();
QueueNextPacket(buffer); // Read more data.
pending_bytes_ += buffer->dwBufferLength;
}
@@ -343,13 +339,6 @@ void PCMWaveOutAudioOutputStream::QueueNextPacket(WAVEHDR *buffer) {
// return to us how many bytes were used.
// TODO(fbarchard): Handle used 0 by queueing more.
- // HACK: Yield if Read() is called too often. On older platforms which are
- // still using the WaveOut backend, we run into synchronization issues where
- // the renderer has not finished filling the shared memory when Read() is
- // called. Reading too early will lead to clicks and pops. See issues:
- // http://crbug.com/161307 and http://crbug.com/61022
- callback_->WaitTillDataReady();
-
// TODO(sergeyu): Specify correct hardware delay for AudioBuffersState.
int frames_filled = callback_->OnMoreData(
audio_bus_.get(), AudioBuffersState(pending_bytes_, 0));