Index: media/audio/audio_output_device.cc |
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc |
index d09e32c4a77c6f2805a5bd95ee42023420339fc0..ef432343173c915a5198096cdefa8487ba640b7a 100644 |
--- a/media/audio/audio_output_device.cc |
+++ b/media/audio/audio_output_device.cc |
@@ -47,20 +47,20 @@ AudioOutputDevice::AudioOutputDevice( |
input_channels_(0), |
callback_(NULL), |
ipc_(ipc), |
- stream_id_(0), |
+ state_(IDLE), |
play_on_start_(true), |
- is_started_(false), |
stopping_hack_(false) { |
CHECK(ipc_); |
+ stream_id_ = ipc_->AddDelegate(this); |
+} |
+ |
+int AudioOutputDevice::stream_id() const { |
+ return stream_id_; |
} |
void AudioOutputDevice::Initialize(const AudioParameters& params, |
RenderCallback* callback) { |
- CHECK_EQ(0, stream_id_) << |
- "AudioOutputDevice::Initialize() must be called before Start()"; |
- |
- CHECK(!callback_); // Calling Initialize() twice? |
- |
+ DCHECK(!callback_) << "Calling Initialize() twice?"; |
audio_parameters_ = params; |
callback_ = callback; |
} |
@@ -77,7 +77,10 @@ void AudioOutputDevice::InitializeIO(const AudioParameters& params, |
AudioOutputDevice::~AudioOutputDevice() { |
// The current design requires that the user calls Stop() before deleting |
// this class. |
- CHECK_EQ(0, stream_id_); |
+ DCHECK(audio_thread_.IsStopped()); |
+ |
+ if (ipc_) |
+ ipc_->RemoveDelegate(stream_id_); |
} |
void AudioOutputDevice::Start() { |
@@ -123,49 +126,44 @@ bool AudioOutputDevice::SetVolume(double volume) { |
void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params, |
int input_channels) { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
- // Make sure we don't create the stream more than once. |
- DCHECK_EQ(0, stream_id_); |
- if (stream_id_) |
- return; |
- |
- stream_id_ = ipc_->AddDelegate(this); |
- ipc_->CreateStream(stream_id_, params, input_channels); |
+ if (state_ == IDLE) { |
+ state_ = CREATING_STREAM; |
+ ipc_->CreateStream(stream_id_, params, input_channels); |
+ } |
} |
void AudioOutputDevice::PlayOnIOThread() { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
- if (stream_id_ && is_started_) |
+ if (state_ == PAUSED) { |
ipc_->PlayStream(stream_id_); |
- else |
+ state_ = PLAYING; |
+ play_on_start_ = false; |
+ } else { |
play_on_start_ = true; |
+ } |
} |
void AudioOutputDevice::PauseOnIOThread(bool flush) { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
- if (stream_id_ && is_started_) { |
+ if (state_ == PLAYING) { |
ipc_->PauseStream(stream_id_); |
if (flush) |
ipc_->FlushStream(stream_id_); |
+ state_ = PAUSED; |
} else { |
// Note that |flush| isn't relevant here since this is the case where |
// the stream is first starting. |
- play_on_start_ = false; |
} |
+ play_on_start_ = false; |
} |
void AudioOutputDevice::ShutDownOnIOThread() { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
// Make sure we don't call shutdown more than once. |
- if (stream_id_) { |
- is_started_ = false; |
- |
- if (ipc_) { |
- ipc_->CloseStream(stream_id_); |
- ipc_->RemoveDelegate(stream_id_); |
- } |
- |
- stream_id_ = 0; |
+ if (state_ >= CREATING_STREAM) { |
+ ipc_->CloseStream(stream_id_); |
+ state_ = IDLE; |
} |
// We can run into an issue where ShutDownOnIOThread is called right after |
@@ -185,7 +183,7 @@ void AudioOutputDevice::ShutDownOnIOThread() { |
void AudioOutputDevice::SetVolumeOnIOThread(double volume) { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
- if (stream_id_) |
+ if (state_ >= PAUSED) |
ipc_->SetVolume(stream_id_, volume); |
} |
@@ -193,7 +191,7 @@ void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegate::State state) { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
// Do nothing if the stream has been closed. |
- if (!stream_id_) |
+ if (state_ < CREATING_STREAM) |
return; |
if (state == AudioOutputIPCDelegate::kError) { |
@@ -222,12 +220,8 @@ void AudioOutputDevice::OnStreamCreated( |
DCHECK_GE(socket_handle, 0); |
#endif |
- // We should only get this callback if stream_id_ is valid. If it is not, |
- // the IPC layer should have closed the shared memory and socket handles |
- // for us and not invoked the callback. The basic assertion is that when |
- // stream_id_ is 0 the AudioOutputDevice instance is not registered as a |
- // delegate and hence it should not receive callbacks. |
- DCHECK(stream_id_); |
+ if (state_ != CREATING_STREAM) |
+ return; |
// We can receive OnStreamCreated() on the IO thread after the client has |
// called Stop() but before ShutDownOnIOThread() is processed. In such a |
@@ -250,15 +244,17 @@ void AudioOutputDevice::OnStreamCreated( |
audio_parameters_, input_channels_, handle, length, callback_)); |
audio_thread_.Start(audio_callback_.get(), socket_handle, |
"AudioOutputDevice"); |
+ state_ = PAUSED; |
// We handle the case where Play() and/or Pause() may have been called |
// multiple times before OnStreamCreated() gets called. |
- is_started_ = true; |
if (play_on_start_) |
PlayOnIOThread(); |
} |
void AudioOutputDevice::OnIPCClosed() { |
+ DCHECK(message_loop()->BelongsToCurrentThread()); |
+ state_ = IPC_CLOSED; |
ipc_ = NULL; |
} |