From 5ef3ab76087ea60d4f87730dc65251b60e89314e Mon Sep 17 00:00:00 2001 From: fokede Date: Tue, 24 Oct 2017 10:48:40 +0300 Subject: [PATCH 1/2] Fixes DirectSound crash on Windows 7. When the player is destroyed, PositionWatcher tried to access already destroyed AudioOutputDSound object. --- src/QtAV/private/AudioOutputBackend.h | 2 +- src/output/audio/AudioOutputDSound.cpp | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) 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..6a96f9e31 100644 --- a/src/output/audio/AudioOutputDSound.cpp +++ b/src/output/audio/AudioOutputDSound.cpp @@ -88,7 +88,7 @@ class AudioOutputDSound Q_DECL_FINAL: public AudioOutputBackend //qWarning("WaitForSingleObjectEx for ao->notify_event error: %#lx", dwResult); continue; } - ao->onCallback(); + if (ao->available) ao->onCallback(); } } }; @@ -192,6 +192,7 @@ bool AudioOutputDSound::close() { available = false; destroy(); + SetEvent(notify_event); CloseHandle(notify_event); // FIXME: is it ok if thread is still waiting? return true; } From 028fcdbcba52d15a510472d565eda7cd4ffa5eff Mon Sep 17 00:00:00 2001 From: fokede Date: Wed, 1 Nov 2017 11:03:17 +0200 Subject: [PATCH 2/2] Fixed crash with thread still waiting. --- src/output/audio/AudioOutputDSound.cpp | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/output/audio/AudioOutputDSound.cpp b/src/output/audio/AudioOutputDSound.cpp index 6a96f9e31..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; } - if (ao->available) ao->onCallback(); + if (ao && ao->available) ao->onCallback(); } } }; @@ -192,8 +199,6 @@ bool AudioOutputDSound::close() { available = false; destroy(); - SetEvent(notify_event); - CloseHandle(notify_event); // FIXME: is it ok if thread is still waiting? return true; }