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

Unified Diff: media/audio/audio_output_controller.h

Issue 11413078: Tab Audio Capture: Browser-side connect/disconnect functionality. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Add done closure to MirroringDestination::RemoveInput(). 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.h
diff --git a/media/audio/audio_output_controller.h b/media/audio/audio_output_controller.h
index 762a9483d0fb51d1bdeed0cfa08a042508bab368..36461e1aee5a5a9f7d5d60bdfdf3fa18b377f257 100644
--- a/media/audio/audio_output_controller.h
+++ b/media/audio/audio_output_controller.h
@@ -65,7 +65,6 @@ namespace media {
class MEDIA_EXPORT AudioOutputController
: public base::RefCountedThreadSafe<AudioOutputController>,
- public AudioOutputStream::AudioSourceCallback,
NON_EXPORTED_BASE(public AudioManager::AudioDeviceListener) {
public:
// An event handler that receives events from the AudioOutputController. The
@@ -139,21 +138,27 @@ class MEDIA_EXPORT AudioOutputController
// Sets the volume of the audio output stream.
void SetVolume(double volume);
- // AudioSourceCallback implementation.
- virtual int OnMoreData(AudioBus* dest,
- AudioBuffersState buffers_state) OVERRIDE;
- virtual int OnMoreIOData(AudioBus* source,
- AudioBus* dest,
- AudioBuffersState buffers_state) OVERRIDE;
- virtual void OnError(AudioOutputStream* stream, int code) OVERRIDE;
- virtual void WaitTillDataReady() OVERRIDE;
-
// AudioDeviceListener implementation. When called AudioOutputController will
// shutdown the existing |stream_|, transition to the kRecreating state,
// create a new stream, and then transition back to an equivalent state prior
// to being called.
virtual void OnDeviceChange() OVERRIDE;
+ // Accessor to audio output parameters.
+ const AudioParameters& params() const { return params_; }
+
+ // Stops the normal audio output stream and creates an AudioSourceCallback to
+ // provide audio data to some other destination. The given object will always
+ // return data when OnMoreData() is invoked, even if the underlying
+ // implementation is paused/stopped. AudioOutputController retains ownership
+ // of the returned object.
+ AudioOutputStream::AudioSourceCallback* Divert();
+
+ // Restores normal audio output behavior for the current playback state.
+ // |asc| is the pointer returned by the previous call to Divert() and becomes
+ // invalid once this method is called.
+ void Revert(AudioOutputStream::AudioSourceCallback* asc);
+
protected:
// Internal state of the source.
enum State {
@@ -172,6 +177,61 @@ class MEDIA_EXPORT AudioOutputController
virtual ~AudioOutputController();
private:
+ // An AudioSourceCallback that allows passing around the underlying SyncReader
DaleCurtis 2012/12/12 01:29:15 Move to CC file?
miu 2012/12/12 03:13:39 Done.
+ // data source between consumers of the data. It does this in a "pass or
+ // delayed pass" scheme that ensures synchronization between timing-sensitive
+ // threads is effectively non-blocking. In addition, Glue ensures that only
+ // one consumer is pulling data from the SyncReader at a time.
+ class Glue
DaleCurtis 2012/12/12 01:29:15 A better name would be nice.
miu 2012/12/12 03:13:39 Done. s/Glue/SourceSharingCallback/
+ : public AudioOutputStream::AudioSourceCallback,
+ public base::RefCountedThreadSafe<Glue> {
DaleCurtis 2012/12/12 01:29:15 Why does this need refcounting?
miu 2012/12/12 03:13:39 An instance has to live until the "pass" completes
+ public:
+ Glue(AudioOutputController* controller, SyncReader* source);
+
+ // Pass the SyncReader to another instance as soon as possible.
+ void PassSoon(const scoped_refptr<Glue>& receiver);
+
+ // AudioSourceCallback implementation.
+ virtual int OnMoreData(AudioBus* dest_bus,
+ AudioBuffersState buffers_state) OVERRIDE;
+ virtual int OnMoreIOData(AudioBus* source_bus,
+ AudioBus* dest_bus,
+ AudioBuffersState buffers_state) OVERRIDE;
+ virtual void OnError(AudioOutputStream* stream, int code) OVERRIDE;
+ virtual void WaitTillDataReady() OVERRIDE;
+
+ private:
+ friend class base::RefCountedThreadSafe<Glue>;
+ virtual ~Glue();
+
+ // Take over reading from |source|.
+ void ReceiveSource(SyncReader* source);
+
+ // Executes a delayed pass (i.e., a pass that was delayed because source_
+ // was in-use at the time PassSoon() was called).
+ void DoDelayedPassWithLockHeld(const scoped_refptr<Glue>& to);
+
+ // Access to parent/owner instance.
+ AudioOutputController* const controller_;
+
+ // Guards passing of SyncReader to another Glue instance. The
+ // implementation should acquire lock_ for only very short operations since
+ // audio threads are timing-sensitive.
+ base::Lock lock_;
+
+ // Audio data source, or NULL if none yet.
+ SyncReader* source_;
+
+ // True while source_ is in-use without lock_ held.
+ bool is_reading_from_source_;
+
+ // When !delayed_pass_.is_null(), source_ is scheduled to be passed as soon
+ // as possible.
+ base::Closure delayed_pass_;
+
+ DISALLOW_COPY_AND_ASSIGN(Glue);
+ };
+
// We are polling sync reader if data became available.
static const int kPollNumAttempts;
static const int kPollPauseInMilliseconds;
@@ -196,12 +256,19 @@ class MEDIA_EXPORT AudioOutputController
// Signals event when done if it is not NULL.
void DoStopCloseAndClearStream(base::WaitableEvent *done);
- AudioManager* audio_manager_;
+ AudioManager* const audio_manager_;
+ const AudioParameters params_;
// |handler_| may be called only if |state_| is not kClosed.
EventHandler* handler_;
+
+ // AudioManager-owned stream.
AudioOutputStream* stream_;
+ // Consumers of audio data which share sync_reader_.
+ scoped_refptr<Glue> stream_glue_;
+ scoped_refptr<Glue> divert_glue_;
+
// The current volume of the audio stream.
double volume_;
@@ -210,10 +277,6 @@ class MEDIA_EXPORT AudioOutputController
// is not required for reading on the audio manager thread.
State state_;
- // The |lock_| must be acquired whenever we access |state_| from a thread
- // other than the audio manager thread.
- base::Lock lock_;
-
// SyncReader is used only in low latency mode for synchronous reading.
SyncReader* sync_reader_;
@@ -224,8 +287,6 @@ class MEDIA_EXPORT AudioOutputController
// Number of times left.
int number_polling_attempts_left_;
- AudioParameters params_;
-
// Used to post delayed tasks to ourselves that we can cancel.
// We don't want the tasks to hold onto a reference as it will slow down
// shutdown and force it to wait for the most delayed task.

Powered by Google App Engine
This is Rietveld 408576698