Index: media/audio/audio_output_device.cc |
diff --git a/media/audio/audio_output_device.cc b/media/audio/audio_output_device.cc |
index 98a75ee71f1de315373dba58c3124f79d8013ce6..48e46f62fc1fae31a7a6656350075c6331c02d0f 100644 |
--- a/media/audio/audio_output_device.cc |
+++ b/media/audio/audio_output_device.cc |
@@ -4,6 +4,7 @@ |
#include "media/audio/audio_output_device.h" |
+#include "base/basictypes.h" |
#include "base/debug/trace_event.h" |
#include "base/message_loop.h" |
#include "base/threading/thread_restrictions.h" |
@@ -40,16 +41,22 @@ class AudioOutputDevice::AudioThreadCallback |
}; |
AudioOutputDevice::AudioOutputDevice( |
- AudioOutputIPC* ipc, |
+ scoped_ptr<AudioOutputIPC> ipc, |
const scoped_refptr<base::MessageLoopProxy>& io_loop) |
: ScopedLoopObserver(io_loop), |
callback_(NULL), |
- ipc_(ipc), |
- stream_id_(0), |
+ ipc_(ipc.Pass()), |
state_(IDLE), |
play_on_start_(true), |
stopping_hack_(false) { |
CHECK(ipc_); |
+ |
+ // The correctness of the code depends on the relative values assigned in the |
+ // State enum. |
+ COMPILE_ASSERT(IPC_CLOSED < IDLE, invalid_enum_value_assignment_0); |
+ COMPILE_ASSERT(IDLE < CREATING_STREAM, invalid_enum_value_assignment_1); |
+ COMPILE_ASSERT(CREATING_STREAM < PAUSED, invalid_enum_value_assignment_2); |
+ COMPILE_ASSERT(PAUSED < PLAYING, invalid_enum_value_assignment_3); |
} |
void AudioOutputDevice::Initialize(const AudioParameters& params, |
@@ -109,16 +116,15 @@ bool AudioOutputDevice::SetVolume(double volume) { |
void AudioOutputDevice::CreateStreamOnIOThread(const AudioParameters& params) { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
if (state_ == IDLE) { |
- stream_id_ = ipc_->AddDelegate(this); |
state_ = CREATING_STREAM; |
- ipc_->CreateStream(stream_id_, params); |
+ ipc_->CreateStream(this, params); |
} |
} |
void AudioOutputDevice::PlayOnIOThread() { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
if (state_ == PAUSED) { |
- ipc_->PlayStream(stream_id_); |
+ ipc_->PlayStream(); |
state_ = PLAYING; |
play_on_start_ = false; |
} else { |
@@ -129,7 +135,7 @@ void AudioOutputDevice::PlayOnIOThread() { |
void AudioOutputDevice::PauseOnIOThread() { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
if (state_ == PLAYING) { |
- ipc_->PauseStream(stream_id_); |
+ ipc_->PauseStream(); |
state_ = PAUSED; |
} |
play_on_start_ = false; |
@@ -138,12 +144,10 @@ void AudioOutputDevice::PauseOnIOThread() { |
void AudioOutputDevice::ShutDownOnIOThread() { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
- // Make sure we don't call shutdown more than once. |
+ // Close the stream, if we haven't already. |
if (state_ >= CREATING_STREAM) { |
- ipc_->CloseStream(stream_id_); |
- ipc_->RemoveDelegate(stream_id_); |
+ ipc_->CloseStream(); |
state_ = IDLE; |
- stream_id_ = 0; |
} |
// We can run into an issue where ShutDownOnIOThread is called right after |
@@ -164,7 +168,7 @@ void AudioOutputDevice::ShutDownOnIOThread() { |
void AudioOutputDevice::SetVolumeOnIOThread(double volume) { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
if (state_ >= CREATING_STREAM) |
- ipc_->SetVolume(stream_id_, volume); |
+ ipc_->SetVolume(volume); |
} |
void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegate::State state) { |
@@ -174,16 +178,27 @@ void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegate::State state) { |
if (state_ < CREATING_STREAM) |
return; |
- if (state == AudioOutputIPCDelegate::kError) { |
- DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(kError)"; |
- // Don't dereference the callback object if the audio thread |
- // is stopped or stopping. That could mean that the callback |
- // object has been deleted. |
- // TODO(tommi): Add an explicit contract for clearing the callback |
- // object. Possibly require calling Initialize again or provide |
- // a callback object via Start() and clear it in Stop(). |
- if (!audio_thread_.IsStopped()) |
- callback_->OnRenderError(); |
+ // TODO(miu): Clean-up inconsistent and incomplete handling here. |
+ // http://crbug.com/180640 |
+ switch (state) { |
+ case AudioOutputIPCDelegate::kPlaying: |
+ case AudioOutputIPCDelegate::kPaused: |
+ NOTIMPLEMENTED(); |
+ break; |
+ case AudioOutputIPCDelegate::kError: |
+ DLOG(WARNING) << "AudioOutputDevice::OnStateChanged(kError)"; |
+ // Don't dereference the callback object if the audio thread |
+ // is stopped or stopping. That could mean that the callback |
+ // object has been deleted. |
+ // TODO(tommi): Add an explicit contract for clearing the callback |
+ // object. Possibly require calling Initialize again or provide |
+ // a callback object via Start() and clear it in Stop(). |
+ if (!audio_thread_.IsStopped()) |
+ callback_->OnRenderError(); |
+ break; |
+ default: |
+ NOTREACHED(); |
+ break; |
} |
} |
@@ -199,6 +214,7 @@ void AudioOutputDevice::OnStreamCreated( |
DCHECK_GE(handle.fd, 0); |
DCHECK_GE(socket_handle, 0); |
#endif |
+ DCHECK_GT(length, 0); |
if (state_ != CREATING_STREAM) |
return; |
@@ -235,7 +251,7 @@ void AudioOutputDevice::OnStreamCreated( |
void AudioOutputDevice::OnIPCClosed() { |
DCHECK(message_loop()->BelongsToCurrentThread()); |
state_ = IPC_CLOSED; |
- ipc_ = NULL; |
+ ipc_.reset(); |
} |
void AudioOutputDevice::WillDestroyCurrentMessageLoop() { |