Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/extern
diff options
context:
space:
mode:
authorJörg Müller <nexyon@gmail.com>2021-03-19 23:42:55 +0300
committerJörg Müller <nexyon@gmail.com>2021-03-19 23:42:55 +0300
commit250a69ee82821f9d2d11325ab15e72b39632df1f (patch)
tree3bb05346c72e324de70c292bc155118f23dd0eac /extern
parent00215692d18d80ba6733784ef54c03a4d7514c6d (diff)
Fix T86728: Blender freezes when playhead is dragged in this .blend
Porting the deadlock bugfix in WASAPI from upstream Audaspace.
Diffstat (limited to 'extern')
-rw-r--r--extern/audaspace/plugins/wasapi/WASAPIDevice.cpp60
-rw-r--r--extern/audaspace/plugins/wasapi/WASAPIDevice.h5
2 files changed, 53 insertions, 12 deletions
diff --git a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
index 241f694feb5..4f213dc8468 100644
--- a/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
+++ b/extern/audaspace/plugins/wasapi/WASAPIDevice.cpp
@@ -35,7 +35,11 @@ void WASAPIDevice::start()
{
lock();
- if(!m_playing)
+ // thread is still running, we can abort stopping it
+ if(m_stop)
+ m_stop = false;
+ // thread is not running, let's start it
+ else if(!m_playing)
{
if(m_thread.joinable())
m_thread.join();
@@ -53,20 +57,35 @@ void WASAPIDevice::updateStream()
UINT32 buffer_size;
data_t* buffer;
+ lock();
+
if(FAILED(m_audio_client->GetBufferSize(&buffer_size)))
+ {
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
+ }
IAudioRenderClient* render_client = nullptr;
const IID IID_IAudioRenderClient = __uuidof(IAudioRenderClient);
if(FAILED(m_audio_client->GetService(IID_IAudioRenderClient, reinterpret_cast<void**>(&render_client))))
+ {
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
+ }
UINT32 padding;
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
{
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
@@ -75,31 +94,40 @@ void WASAPIDevice::updateStream()
if(FAILED(render_client->GetBuffer(length, &buffer)))
{
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
- lock();
-
mix((data_t*)buffer, length);
- unlock();
-
if(FAILED(render_client->ReleaseBuffer(length, 0)))
{
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
+ unlock();
+
m_audio_client->Start();
auto sleepDuration = std::chrono::milliseconds(buffer_size * 1000 / int(m_specs.rate) / 2);
for(;;)
{
+ lock();
+
if(FAILED(m_audio_client->GetCurrentPadding(&padding)))
{
m_audio_client->Stop();
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
@@ -109,44 +137,52 @@ void WASAPIDevice::updateStream()
{
m_audio_client->Stop();
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
- lock();
-
mix((data_t*)buffer, length);
- unlock();
-
if(FAILED(render_client->ReleaseBuffer(length, 0)))
{
m_audio_client->Stop();
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
// stop thread
- if(!m_playing)
+ if(m_stop)
{
m_audio_client->Stop();
SafeRelease(&render_client);
+ m_playing = false;
+ m_stop = false;
+ unlock();
return;
}
+ unlock();
+
std::this_thread::sleep_for(sleepDuration);
}
}
void WASAPIDevice::playing(bool playing)
{
- if(!m_playing && playing)
+ if((!m_playing || m_stop) && playing)
start();
else
- m_playing = playing;
+ m_stop = true;
}
WASAPIDevice::WASAPIDevice(DeviceSpecs specs, int buffersize) :
m_playing(false),
+ m_stop(false),
m_imm_device_enumerator(nullptr),
m_imm_device(nullptr),
diff --git a/extern/audaspace/plugins/wasapi/WASAPIDevice.h b/extern/audaspace/plugins/wasapi/WASAPIDevice.h
index b7b520e802c..ae25a09c432 100644
--- a/extern/audaspace/plugins/wasapi/WASAPIDevice.h
+++ b/extern/audaspace/plugins/wasapi/WASAPIDevice.h
@@ -48,6 +48,11 @@ private:
*/
bool m_playing;
+ /**
+ * Whether the current playback should stop.
+ */
+ bool m_stop;
+
IMMDeviceEnumerator* m_imm_device_enumerator;
IMMDevice* m_imm_device;
IAudioClient* m_audio_client;