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

Unified Diff: media/audio/audio_output_controller.cc

Issue 11413078: Tab Audio Capture: Browser-side connect/disconnect functionality. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Remove WCAudioInputStream changes (split into another change). Created 8 years 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_controller.cc
diff --git a/media/audio/audio_output_controller.cc b/media/audio/audio_output_controller.cc
index 50850c9265cdd2b0f503e97994a122b70167047d..ac1ca355eb0110da0becb6fd79b57fef080f1d50 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -29,6 +29,7 @@ AudioOutputController::AudioOutputController(AudioManager* audio_manager,
const AudioParameters& params,
SyncReader* sync_reader)
: audio_manager_(audio_manager),
+ params_(params),
handler_(handler),
stream_(NULL),
volume_(1.0),
@@ -36,7 +37,6 @@ AudioOutputController::AudioOutputController(AudioManager* audio_manager,
sync_reader_(sync_reader),
message_loop_(audio_manager->GetMessageLoop()),
number_polling_attempts_left_(0),
- params_(params),
ALLOW_THIS_IN_INITIALIZER_LIST(weak_this_(this)) {
}
@@ -70,13 +70,10 @@ scoped_refptr<AudioOutputController> AudioOutputController::Create(
if (!params.IsValid() || !audio_manager)
return NULL;
- // Starts the audio controller thread.
scoped_refptr<AudioOutputController> controller(new AudioOutputController(
audio_manager, event_handler, params, sync_reader));
-
controller->message_loop_->PostTask(FROM_HERE, base::Bind(
&AudioOutputController::DoCreate, controller));
-
return controller;
}
@@ -138,10 +135,9 @@ void AudioOutputController::DoCreate() {
return;
}
- // Everything started okay, so register for state change callbacks if we have
- // not already done so.
- if (state_ != kRecreating)
- audio_manager_->AddOutputDeviceChangeListener(this);
+ // Everything started okay, so re-register for state change callbacks (the
+ // call to DoStopCloseAndClearStream() above de-registered this instance).
+ audio_manager_->AddOutputDeviceChangeListener(this);
DaleCurtis 2012/12/05 23:35:14 I don't see where you're removing the device chang
miu 2012/12/11 02:30:45 The call to DoStopCloseAndClearStream() above call
// We have successfully opened the stream. Set the initial volume.
stream_->SetVolume(volume_);
@@ -215,7 +211,8 @@ void AudioOutputController::StartStream() {
state_ = kPlaying;
// We start the AudioOutputStream lazily.
- stream_->Start(this);
+ if (stream_)
DaleCurtis 2012/12/05 23:35:14 stream_ should always be valid here. why not check
miu 2012/12/11 02:30:45 I had changed the semantics so that stream_ is NUL
+ stream_->Start(this);
// Tell the event handler that we are now playing.
handler_->OnPlaying(this);
@@ -305,11 +302,12 @@ int AudioOutputController::OnMoreIOData(AudioBus* source,
TRACE_EVENT0("audio", "AudioOutputController::OnMoreIOData");
{
- // Check state and do nothing if we are not playing.
+ // Check state. When not playing, fill the destination with zeros.
// We are on the hardware audio thread, so lock is needed.
base::AutoLock auto_lock(lock_);
if (state_ != kPlaying) {
- return 0;
+ dest->Zero();
+ return dest->frames();
}
}
@@ -353,7 +351,6 @@ void AudioOutputController::DoStopCloseAndClearStream(WaitableEvent* done) {
stream_ = NULL;
audio_manager_->RemoveOutputDeviceChangeListener(this);
- audio_manager_ = NULL;
weak_this_.InvalidateWeakPtrs();
}
@@ -366,16 +363,11 @@ void AudioOutputController::DoStopCloseAndClearStream(WaitableEvent* done) {
void AudioOutputController::OnDeviceChange() {
DCHECK(message_loop_->BelongsToCurrentThread());
- // We should always have a stream by this point.
DaleCurtis 2012/12/05 23:35:14 Is this not true anymore?
miu 2012/12/11 02:30:45 Done. (Reverted back to original behavior.)
- CHECK(stream_);
-
- // Preserve the original state and shutdown the stream.
+ // Preserve the original state.
State original_state = state_;
- stream_->Stop();
- stream_->Close();
- stream_ = NULL;
- // Recreate the stream, exit if we ran into an error.
+ // Recreate the stream (DoCreate() will first shut down an existing stream).
+ // Exit if we ran into an error.
state_ = kRecreating;
DoCreate();
if (!stream_ || state_ == kError)
@@ -385,6 +377,7 @@ void AudioOutputController::OnDeviceChange() {
switch (original_state) {
case kStarting:
case kPlaying:
+ DoSetVolume(volume_);
DoPlay();
return;
case kCreated:
@@ -397,4 +390,39 @@ void AudioOutputController::OnDeviceChange() {
}
}
+AudioOutputStream::AudioSourceCallback* AudioOutputController::Divert() {
+ // Assumption: AudioRendererHost is calling this method on the IO
+ // BrowserThread.
+ DCHECK(!message_loop_->BelongsToCurrentThread());
DaleCurtis 2012/12/05 23:35:14 Is this helpful? It doesn't really matter what thr
miu 2012/12/11 02:30:45 Done.
+
+ // Block until stream closure is complete because, otherwise, it's possible
+ // for two entities to be pulling audio data at the same time. In addition,
+ // a side effect of closing the stream is that this controller will be
+ // de-registered from device change events (from AudioManager) during the
+ // "divert."
+ base::WaitableEvent blocker(true, false);
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioOutputController::DoStopCloseAndClearStream, this,
+ &blocker));
+ blocker.Wait();
DaleCurtis 2012/12/05 23:35:14 Hmmm, seems risky. You're blocking the IO thread w
miu 2012/12/11 02:30:45 I changed my approach, and came up with something
+
+ return this;
+}
+
+void AudioOutputController::Revert(
+ AudioOutputStream::AudioSourceCallback* asc) {
+ // Assumption: AudioRendererHost is calling this method on the IO
+ // BrowserThread.
+ DCHECK(!message_loop_->BelongsToCurrentThread());
+
+ DCHECK_EQ(this, asc);
DaleCurtis 2012/12/05 23:35:14 Again seems odd.
miu 2012/12/11 02:30:45 Done.
+
+ // The following re-creates the normal audio output stream and places it in
+ // the correct playback state. It also re-registers this controller for
+ // device change events from AudioManager.
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(&AudioOutputController::OnDeviceChange, this));
+}
+
} // namespace media

Powered by Google App Engine
This is Rietveld 408576698