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. |