Chromium Code Reviews| Index: media/audio/win/waveout_output_win.h |
| =================================================================== |
| --- media/audio/win/waveout_output_win.h (revision 110574) |
| +++ media/audio/win/waveout_output_win.h (working copy) |
| @@ -11,6 +11,9 @@ |
| #include <mmreg.h> |
| #include "base/basictypes.h" |
| +#include "base/memory/ref_counted.h" |
| +#include "base/memory/scoped_ptr.h" |
| +#include "base/synchronization/lock.h" |
| #include "base/win/scoped_handle.h" |
| #include "media/audio/audio_io.h" |
| #include "media/audio/audio_parameters.h" |
| @@ -27,10 +30,13 @@ |
| // than one thread so it is important to have some form of synchronization if |
| // you are keeping state in it. |
| class PCMWaveOutAudioOutputStream : public AudioOutputStream { |
| + friend class PlayingObject; |
| + |
| public: |
| // The ctor takes all the usual parameters, plus |manager| which is the |
| - // the audio manager who is creating this object and |device_id| which |
| - // is provided by the operating system. |
| + // the audio manager who is creating this object and on which message loop |
| + // "feeder" callbacks are running, and |device_id| which is provided by the |
| + // operating system. |
| PCMWaveOutAudioOutputStream(AudioManagerWin* manager, |
| const AudioParameters& params, |
| int num_buffers, |
| @@ -56,17 +62,56 @@ |
| PCMA_CLOSED // Device has been released. |
| }; |
| - // Windows calls us back to feed more data to the device here. See msdn |
| - // documentation for 'waveOutProc' for details about the parameters. |
| + // Internal reference-counted class used to speed up stopping of audio stream. |
| + // By creating that separate object and passing it as argument we can stop |
| + // playing immediately, not waiting till all scheduled callbacks finish. |
| + // It is reference-counted, so it would be eventualy deleted. |
| + class PlayingObject : |
| + public base::RefCountedThreadSafe<PlayingObject> { |
| + public: |
| + // Accessors. |
| + base::Lock* lock() { |
| + return &lock_; |
| + } |
| + bool playing() const { |
| + return stream_ != NULL; |
|
tommi (sloooow) - chröme
2011/11/19 17:23:27
should we lock lock_ here and in stop_playing() or
|
| + } |
| + void stop_playing() { |
| + stream_ = NULL; |
| + } |
| + |
| + PlayingObject(PCMWaveOutAudioOutputStream *stream); |
|
tommi (sloooow) - chröme
2011/11/19 17:23:27
PCMWaveOutAudioOutputStream* stream
|
| + ~PlayingObject(); |
| + // Feed the buffer to waveOut. |
| + // Called on the audio manager thread. |
| + void FeedBuffer(WAVEHDR* buffer, HWAVEOUT hwo); |
| + |
| + private: |
| + // Lock used to avoid the conflict between filling audio buffers and |
| + // stopping the stream. |
| + base::Lock lock_; |
| + // Pointer to the parent object. Not owned. |
| + PCMWaveOutAudioOutputStream *stream_; |
|
tommi (sloooow) - chröme
2011/11/19 17:23:27
PCMWaveOutAudioOutputStream* stream_;
|
| + }; |
| + |
| + // Returns pointer to the n-th buffer. |
| + inline WAVEHDR* GetBuffer(int n) const; |
| + |
| + // Size of one buffer in bytes, rounded up if necessary. |
| + inline size_t BufferSize() const; |
| + |
| + // Windows calls us back to free the buffer. See msdn documentation for |
| + // 'waveOutProc' for details about the parameters. |
| static void CALLBACK WaveCallback(HWAVEOUT hwo, UINT msg, DWORD_PTR instance, |
| DWORD_PTR param1, DWORD_PTR param2); |
| // If windows reports an error this function handles it and passes it to |
| // the attached AudioSourceCallback::OnError(). |
| void HandleError(MMRESULT error); |
| - // Allocates and prepares the memory that will be used for playback. Only |
| - // two buffers are created. |
| + |
| + // Allocates and prepares the memory that will be used for playback. |
| void SetupBuffers(); |
| + |
| // Deallocates the memory allocated in SetupBuffers. |
| void FreeBuffers(); |
| @@ -107,18 +152,12 @@ |
| // Handle to the instance of the wave device. |
| HWAVEOUT waveout_; |
| - // Pointer to the first allocated audio buffer. This object owns it. |
| - WAVEHDR* buffer_; |
| + // Pointer to the allocated audio buffers, we allocate all buffers in one big |
| + // chunk. This object owns them. |
| + scoped_array<char> buffers_; |
| - // Lock used to prevent stopping the hardware callback thread while it is |
| - // pending for data or feeding it to audio driver, because doing that causes |
| - // the deadlock. Main thread gets that lock before stopping the playback. |
| - // Callback tries to acquire that lock before entering critical code. If |
| - // acquire fails then main thread is stopping the playback, callback should |
| - // immediately return. |
| - // Use Windows-specific lock, not Chrome one, because there is limited set of |
| - // functions callback can use. |
| - CRITICAL_SECTION lock_; |
| + // Infamous aux object. |
|
tommi (sloooow) - chröme
2011/11/19 17:23:27
hah!
|
| + scoped_refptr<PlayingObject> playing_object_; |
| DISALLOW_COPY_AND_ASSIGN(PCMWaveOutAudioOutputStream); |
| }; |