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

Unified Diff: media/audio/audio_output_device.cc

Issue 11359196: Associate audio streams with their source/destination RenderView. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased; and numerous clean-ups. Created 8 years, 1 month 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
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..18fabdc51fb9cc3b8f04fa37abc029dd61b12ee7 100644
--- a/media/audio/audio_output_device.cc
+++ b/media/audio/audio_output_device.cc
@@ -46,21 +46,32 @@ AudioOutputDevice::AudioOutputDevice(
: ScopedLoopObserver(io_loop),
input_channels_(0),
callback_(NULL),
- ipc_(ipc),
- stream_id_(0),
+ stream_id_(-1),
+ state_(kIpcClosed),
play_on_start_(true),
- is_started_(false),
stopping_hack_(false) {
- CHECK(ipc_);
+ CHECK(ipc);
+ message_loop()->PostTask(FROM_HERE,
+ base::Bind(&AudioOutputDevice::RegisterDelegateOnIOThread, this, ipc));
}
-void AudioOutputDevice::Initialize(const AudioParameters& params,
- RenderCallback* callback) {
- CHECK_EQ(0, stream_id_) <<
- "AudioOutputDevice::Initialize() must be called before Start()";
+void AudioOutputDevice::RegisterDelegateOnIOThread(AudioOutputIPC* ipc) {
+ DCHECK(message_loop()->BelongsToCurrentThread());
+ DCHECK_EQ(kIpcClosed, state_);
+ ipc_ = ipc->AsWeakPtr();
+ stream_id_ = ipc_ ? ipc_->AddDelegate(this) : 0;
+ if (stream_id_ > 0)
+ state_ = kIdle;
+}
- CHECK(!callback_); // Calling Initialize() twice?
+int AudioOutputDevice::stream_id() const {
+ DCHECK_LE(0, stream_id_) << "Call to stream_id() before being initialized.";
+ return stream_id_;
+}
+void AudioOutputDevice::Initialize(const AudioParameters& params,
+ RenderCallback* callback) {
+ DCHECK(!callback_) << "Calling Initialize() twice?";
audio_parameters_ = params;
callback_ = callback;
}
@@ -75,9 +86,8 @@ 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_);
+ message_loop()->PostTask(FROM_HERE,
+ base::Bind(&AudioOutputIPC::RemoveDelegate, ipc_, stream_id_));
}
void AudioOutputDevice::Start() {
@@ -123,49 +133,47 @@ 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_ == kIdle && ipc_) {
+ state_ = kCreatingStream;
+ ipc_->CreateStream(stream_id_, params, input_channels);
+ }
}
void AudioOutputDevice::PlayOnIOThread() {
DCHECK(message_loop()->BelongsToCurrentThread());
- if (stream_id_ && is_started_)
+ if (state_ == kPaused && ipc_) {
ipc_->PlayStream(stream_id_);
- else
+ state_ = kPlaying;
+ play_on_start_ = false;
+ } else {
play_on_start_ = true;
+ }
}
void AudioOutputDevice::PauseOnIOThread(bool flush) {
DCHECK(message_loop()->BelongsToCurrentThread());
- if (stream_id_ && is_started_) {
- ipc_->PauseStream(stream_id_);
- if (flush)
- ipc_->FlushStream(stream_id_);
+ if (state_ == kPlaying) {
+ if (ipc_) {
+ ipc_->PauseStream(stream_id_);
+ if (flush)
+ ipc_->FlushStream(stream_id_);
+ }
+ state_ = kPaused;
} 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_) {
+ if (state_ >= kCreatingStream) {
+ if (ipc_)
ipc_->CloseStream(stream_id_);
- ipc_->RemoveDelegate(stream_id_);
- }
-
- stream_id_ = 0;
+ state_ = kIdle;
}
// We can run into an issue where ShutDownOnIOThread is called right after
@@ -185,7 +193,7 @@ void AudioOutputDevice::ShutDownOnIOThread() {
void AudioOutputDevice::SetVolumeOnIOThread(double volume) {
DCHECK(message_loop()->BelongsToCurrentThread());
- if (stream_id_)
+ if (state_ >= kPaused && ipc_)
ipc_->SetVolume(stream_id_, volume);
}
@@ -193,7 +201,7 @@ void AudioOutputDevice::OnStateChanged(AudioOutputIPCDelegate::State state) {
DCHECK(message_loop()->BelongsToCurrentThread());
// Do nothing if the stream has been closed.
- if (!stream_id_)
+ if (state_ < kCreatingStream)
return;
if (state == AudioOutputIPCDelegate::kError) {
@@ -222,12 +230,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_ != kCreatingStream)
+ return;
// We can receive OnStreamCreated() on the IO thread after the client has
// called Stop() but before ShutDownOnIOThread() is processed. In such a
@@ -250,16 +254,18 @@ void AudioOutputDevice::OnStreamCreated(
audio_parameters_, input_channels_, handle, length, callback_));
audio_thread_.Start(audio_callback_.get(), socket_handle,
"AudioOutputDevice");
+ state_ = kPaused;
// 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() {
- ipc_ = NULL;
+ DCHECK(message_loop()->BelongsToCurrentThread());
+ state_ = kIpcClosed;
+ ipc_.reset();
}
void AudioOutputDevice::WillDestroyCurrentMessageLoop() {

Powered by Google App Engine
This is Rietveld 408576698