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

Unified Diff: media/audio/audio_output_controller.cc

Issue 16103007: Privitize WaitTillDataReady() and DataReady(). (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Gotta catch'em all! Created 7 years, 7 months 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: media/audio/audio_output_controller.cc
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index 8e33c7fc892893cd9e889eb660de433b21458885..aea644017610950d77ac9ee6078ea0110b2c6c67 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;
« no previous file with comments | « media/audio/audio_output_controller.h ('k') | media/audio/audio_output_controller_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698