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

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: Simplify! 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..1f40a05d7ac6d279e0afbe58143a44051e593059 100644
--- a/media/audio/audio_output_controller.cc
+++ b/media/audio/audio_output_controller.cc
@@ -29,14 +29,15 @@ AudioOutputController::AudioOutputController(AudioManager* audio_manager,
const AudioParameters& params,
SyncReader* sync_reader)
: audio_manager_(audio_manager),
+ params_(params),
handler_(handler),
stream_(NULL),
+ diverting_to_stream_(NULL),
volume_(1.0),
state_(kEmpty),
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 +71,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;
}
@@ -120,7 +118,8 @@ void AudioOutputController::DoCreate() {
DCHECK(state_ == kEmpty || state_ == kRecreating) << state_;
DoStopCloseAndClearStream(NULL);
- stream_ = audio_manager_->MakeAudioOutputStreamProxy(params_);
+ stream_ = diverting_to_stream_ ? diverting_to_stream_ :
+ audio_manager_->MakeAudioOutputStreamProxy(params_);
if (!stream_) {
state_ = kError;
@@ -138,9 +137,11 @@ void AudioOutputController::DoCreate() {
return;
}
- // Everything started okay, so register for state change callbacks if we have
- // not already done so.
- if (state_ != kRecreating)
+ // Everything started okay, so re-register for state change callbacks if
+ // stream_ was created via AudioManager. Note: The call to
+ // DoStopCloseAndClearStream() above called
+ // RemoveOutputDeviceChangeListener().
+ if (stream_ != diverting_to_stream_)
audio_manager_->AddOutputDeviceChangeListener(this);
// We have successfully opened the stream. Set the initial volume.
@@ -348,13 +349,17 @@ void AudioOutputController::DoStopCloseAndClearStream(WaitableEvent* done) {
// Allow calling unconditionally and bail if we don't have a stream_ to close.
if (stream_) {
+ // De-register from state change callbacks if stream_ was created via
+ // AudioManager.
+ if (stream_ != diverting_to_stream_)
+ audio_manager_->RemoveOutputDeviceChangeListener(this);
+
stream_->Stop();
stream_->Close();
+ if (stream_ == diverting_to_stream_)
+ diverting_to_stream_ = NULL;
stream_ = NULL;
- audio_manager_->RemoveOutputDeviceChangeListener(this);
- audio_manager_ = NULL;
-
weak_this_.InvalidateWeakPtrs();
}
@@ -366,16 +371,9 @@ void AudioOutputController::DoStopCloseAndClearStream(WaitableEvent* done) {
void AudioOutputController::OnDeviceChange() {
DCHECK(message_loop_->BelongsToCurrentThread());
- // We should always have a stream by this point.
- CHECK(stream_);
-
- // Preserve the original state and shutdown the stream.
- 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.
+ const State original_state = state_;
state_ = kRecreating;
DaleCurtis 2012/12/17 20:00:47 Is this state necessary anymore? Should DoStopClos
miu 2012/12/19 00:22:57 Yes, it's still necessary. The code on line 155 u
DoCreate();
if (!stream_ || state_ == kError)
@@ -397,4 +395,31 @@ void AudioOutputController::OnDeviceChange() {
}
}
+void AudioOutputController::DivertToStream(AudioOutputStream* to_stream) {
+ if (!message_loop_->BelongsToCurrentThread()) {
DaleCurtis 2012/12/17 20:00:47 Which threads will be calling this?
miu 2012/12/19 00:22:57 The IO thread (from AudioRendererHost). Added Thr
+ message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&AudioOutputController::DivertToStream, this, to_stream));
+ return;
+ }
+
+ DCHECK(!diverting_to_stream_);
+ diverting_to_stream_ = to_stream;
DaleCurtis 2012/12/17 20:00:47 I suspect this might have issues if it gets fired
miu 2012/12/19 00:22:57 See DCHECK one line down. ;-)
+ DCHECK_NE(kClosed, state_);
+ OnDeviceChange();
+}
+
+void AudioOutputController::RevertDiversion() {
+ if (!message_loop_->BelongsToCurrentThread()) {
DaleCurtis 2012/12/17 20:00:47 Ditto.
miu 2012/12/19 00:22:57 Done.
+ message_loop_->PostTask(
+ FROM_HERE, base::Bind(&AudioOutputController::RevertDiversion, this));
+ return;
+ }
+
+ if (state_ != kClosed) {
+ OnDeviceChange();
+ DCHECK(!diverting_to_stream_);
+ }
+}
+
} // namespace media

Powered by Google App Engine
This is Rietveld 408576698