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

Unified Diff: media/audio/audio_output_controller.cc

Issue 8371013: Harden audio output controller making it safe to call Pause() before (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 9 years, 2 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
===================================================================
--- media/audio/audio_output_controller.cc (revision 106670)
+++ media/audio/audio_output_controller.cc (working copy)
@@ -176,9 +176,10 @@
// We can start from created or paused state.
if (state_ != kCreated && state_ != kPaused)
return;
- state_ = kPlaying;
if (LowLatencyMode()) {
+ state_ = kStarting;
+
// Ask for first packet.
sync_reader_->UpdatePendingBytes(0);
@@ -197,13 +198,20 @@
void AudioOutputController::PollAndStartIfDataReady() {
DCHECK_EQ(message_loop_, MessageLoop::current());
- // Being paranoic: do nothing if we were stopped/paused
- // after DoPlay() but before DoStartStream().
- if (state_ != kPlaying)
+ // Being paranoic: do nothing if state unexpectedly changed.
+ if ((state_ != kStarting) && (state_ != kPausedWhenStarting))
return;
- if (--number_polling_attempts_left_ == 0 || sync_reader_->DataReady()) {
+ bool pausing = (state_ == kPausedWhenStarting);
+ // If we are ready to start the stream, start it.
+ // Of course we may have to stop it immediately...
+ if (--number_polling_attempts_left_ == 0 ||
+ pausing ||
+ sync_reader_->DataReady()) {
StartStream();
+ if (pausing) {
+ DoPause();
+ }
} else {
message_loop_->PostDelayedTask(
FROM_HERE,
@@ -214,6 +222,7 @@
void AudioOutputController::StartStream() {
DCHECK_EQ(message_loop_, MessageLoop::current());
+ state_ = kPlaying;
// We start the AudioOutputStream lazily.
stream_->Start(this);
@@ -225,22 +234,32 @@
void AudioOutputController::DoPause() {
DCHECK_EQ(message_loop_, MessageLoop::current());
- // We can pause from started state.
- if (state_ != kPlaying)
- return;
- state_ = kPaused;
+ switch (state_) {
+ case kStarting:
+ // We were asked to pause while starting. There is delayed task that will
+ // try starting playback, and there is no way to remove that task from the
+ // queue. If we stop now that task will be executed anyway.
+ // Delay pausing, let delayed task to do pause after it start playback.
+ state_ = kPausedWhenStarting;
+ break;
+ case kPlaying:
+ state_ = kPaused;
- // Then we stop the audio device. This is not the perfect solution because
- // it discards all the internal buffer in the audio device.
- // TODO(hclam): Actually pause the audio device.
- stream_->Stop();
+ // Then we stop the audio device. This is not the perfect solution
+ // because it discards all the internal buffer in the audio device.
+ // TODO(hclam): Actually pause the audio device.
+ stream_->Stop();
- if (LowLatencyMode()) {
- // Send a special pause mark to the low-latency audio thread.
- sync_reader_->UpdatePendingBytes(kPauseMark);
+ if (LowLatencyMode()) {
+ // Send a special pause mark to the low-latency audio thread.
+ sync_reader_->UpdatePendingBytes(kPauseMark);
+ }
+
+ handler_->OnPaused(this);
+ break;
+ default:
+ return;
}
-
- handler_->OnPaused(this);
}
void AudioOutputController::DoFlush() {
@@ -287,10 +306,17 @@
// right away but when the stream is created we'll set the volume.
volume_ = volume;
- if (state_ != kPlaying && state_ != kPaused && state_ != kCreated)
- return;
-
- stream_->SetVolume(volume_);
+ switch (state_) {
+ case kCreated:
+ case kStarting:
+ case kPausedWhenStarting:
+ case kPlaying:
+ case kPaused:
+ stream_->SetVolume(volume_);
+ break;
+ default:
+ return;
+ }
}
void AudioOutputController::DoReportError(int code) {
« 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