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); |
}; |