diff --git a/src/QtAV/private/AudioOutputBackend.h b/src/QtAV/private/AudioOutputBackend.h index 012aa3e6f..52cee664b 100644 --- a/src/QtAV/private/AudioOutputBackend.h +++ b/src/QtAV/private/AudioOutputBackend.h @@ -34,7 +34,7 @@ class Q_AV_PRIVATE_EXPORT AudioOutputBackend : public QObject Q_OBJECT public: AudioOutput *audio; - bool available; // default is true. set to false when failed to create backend + volatile bool available; // default is true. set to false when failed to create backend int buffer_size; int buffer_count; AudioFormat format; diff --git a/src/output/audio/AudioOutputDSound.cpp b/src/output/audio/AudioOutputDSound.cpp index 227fba991..db5fe3354 100644 --- a/src/output/audio/AudioOutputDSound.cpp +++ b/src/output/audio/AudioOutputDSound.cpp @@ -26,6 +26,7 @@ #include #include #include +#include #include #define DIRECTSOUND_VERSION 0x0600 #include @@ -58,7 +59,13 @@ class AudioOutputDSound Q_DECL_FINAL: public AudioOutputBackend bool unloadDll(); bool init(); bool destroy() { - SafeRelease(¬ify); + if (notify_event) { + SetEvent(notify_event); + SafeRelease(¬ify); + watcher.wait(); + CloseHandle( notify_event ); // FIXME: is it ok if thread is still waiting? + notify_event = NULL; + } SafeRelease(&prim_buf); SafeRelease(&stream_buf); SafeRelease(&dsound); @@ -77,18 +84,18 @@ class AudioOutputDSound Q_DECL_FINAL: public AudioOutputBackend int write_offset; ///offset of the write cursor in the direct sound buffer QAtomicInt buffers_free; class PositionWatcher : public QThread { - AudioOutputDSound *ao; + QPointer ao; public: PositionWatcher(AudioOutputDSound* dsound) : ao(dsound) {} void run() Q_DECL_OVERRIDE { DWORD dwResult = 0; - while (ao->available) { + while (ao && ao->available) { dwResult = WaitForSingleObjectEx(ao->notify_event, 2000, FALSE); if (dwResult != WAIT_OBJECT_0) { //qWarning("WaitForSingleObjectEx for ao->notify_event error: %#lx", dwResult); continue; } - ao->onCallback(); + if (ao && ao->available) ao->onCallback(); } } }; @@ -192,7 +199,6 @@ bool AudioOutputDSound::close() { available = false; destroy(); - CloseHandle(notify_event); // FIXME: is it ok if thread is still waiting? return true; }