mirror of
https://gitlab.winehq.org/wine/wine-staging.git
synced 2024-11-21 16:46:54 -08:00
Added patch to ignore queued xaudio2 AL buffers after Stop.
This commit is contained in:
parent
97e7c4ffaa
commit
99e7c1d29a
@ -414,6 +414,7 @@ patch_enable_all ()
|
||||
enable_wtsapi32_WTSQueryUserToken="$1"
|
||||
enable_wuauserv_Dummy_Service="$1"
|
||||
enable_wusa_MSU_Package_Installer="$1"
|
||||
enable_xaudio2_7_Abandon_Albufs="$1"
|
||||
}
|
||||
|
||||
# Enable or disable all categories
|
||||
@ -1425,6 +1426,9 @@ patch_enable ()
|
||||
wusa-MSU_Package_Installer)
|
||||
enable_wusa_MSU_Package_Installer="$2"
|
||||
;;
|
||||
xaudio2_7-Abandon_Albufs)
|
||||
enable_xaudio2_7_Abandon_Albufs="$2"
|
||||
;;
|
||||
*)
|
||||
return 1
|
||||
;;
|
||||
@ -8302,6 +8306,21 @@ if test "$enable_wusa_MSU_Package_Installer" -eq 1; then
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
# Patchset xaudio2_7-Abandon_Albufs
|
||||
# |
|
||||
# | This patchset fixes the following Wine bugs:
|
||||
# | * [#40963] Ignore queued xaudio2 AL buffers after Stop
|
||||
# |
|
||||
# | Modified files:
|
||||
# | * dlls/xaudio2_7/tests/xaudio2.c, dlls/xaudio2_7/xaudio_dll.c, dlls/xaudio2_7/xaudio_private.h
|
||||
# |
|
||||
if test "$enable_xaudio2_7_Abandon_Albufs" -eq 1; then
|
||||
patch_apply xaudio2_7-Abandon_Albufs/0001-xaudio2-Ignore-queued-AL-buffers-after-Stop.patch
|
||||
(
|
||||
echo '+ { "Andrew Eikum", "xaudio2: Ignore queued AL buffers after Stop.", 1 },';
|
||||
) >> "$patchlist"
|
||||
fi
|
||||
|
||||
|
||||
if test "$enable_patchlist" -eq 1; then
|
||||
|
||||
|
@ -0,0 +1,222 @@
|
||||
From 14d181155cd442b6f4b06c9837d6541e9d574fff Mon Sep 17 00:00:00 2001
|
||||
From: Andrew Eikum <aeikum@codeweavers.com>
|
||||
Date: Fri, 22 Jul 2016 10:21:20 -0500
|
||||
Subject: xaudio2: Ignore queued AL buffers after Stop
|
||||
|
||||
Changes by Sebastian Lackner <sebastian@fds-team.de>:
|
||||
* Fixed flawed logic to skip abandoned buffers.
|
||||
---
|
||||
dlls/xaudio2_7/tests/xaudio2.c | 78 +++++++++++++++++++++++++++++++++++++++++
|
||||
dlls/xaudio2_7/xaudio_dll.c | 37 +++++++++++++++----
|
||||
dlls/xaudio2_7/xaudio_private.h | 2 +-
|
||||
3 files changed, 109 insertions(+), 8 deletions(-)
|
||||
|
||||
diff --git a/dlls/xaudio2_7/tests/xaudio2.c b/dlls/xaudio2_7/tests/xaudio2.c
|
||||
index 54176ea..ff402f8 100644
|
||||
--- a/dlls/xaudio2_7/tests/xaudio2.c
|
||||
+++ b/dlls/xaudio2_7/tests/xaudio2.c
|
||||
@@ -841,6 +841,82 @@ static void test_submix(IXAudio2 *xa)
|
||||
IXAudio2MasteringVoice_DestroyVoice(master);
|
||||
}
|
||||
|
||||
+static void test_flush(IXAudio2 *xa)
|
||||
+{
|
||||
+ HRESULT hr;
|
||||
+ IXAudio2MasteringVoice *master;
|
||||
+ IXAudio2SourceVoice *src;
|
||||
+ WAVEFORMATEX fmt;
|
||||
+ XAUDIO2_BUFFER buf;
|
||||
+ XAUDIO2_VOICE_STATE state;
|
||||
+
|
||||
+ XA2CALL_0V(StopEngine);
|
||||
+
|
||||
+ if(xaudio27)
|
||||
+ hr = IXAudio27_CreateMasteringVoice((IXAudio27*)xa, &master, 2, 44100, 0, 0, NULL);
|
||||
+ else
|
||||
+ hr = IXAudio2_CreateMasteringVoice(xa, &master, 2, 44100, 0, NULL, NULL, AudioCategory_GameEffects);
|
||||
+ ok(hr == S_OK, "CreateMasteringVoice failed: %08x\n", hr);
|
||||
+
|
||||
+ fmt.wFormatTag = WAVE_FORMAT_IEEE_FLOAT;
|
||||
+ fmt.nChannels = 2;
|
||||
+ fmt.nSamplesPerSec = 44100;
|
||||
+ fmt.wBitsPerSample = 32;
|
||||
+ fmt.nBlockAlign = fmt.nChannels * fmt.wBitsPerSample / 8;
|
||||
+ fmt.nAvgBytesPerSec = fmt.nSamplesPerSec * fmt.nBlockAlign;
|
||||
+ fmt.cbSize = 0;
|
||||
+
|
||||
+ XA2CALL(CreateSourceVoice, &src, &fmt, 0, 1.f, NULL, NULL, NULL);
|
||||
+ ok(hr == S_OK, "CreateSourceVoice failed: %08x\n", hr);
|
||||
+
|
||||
+ memset(&buf, 0, sizeof(buf));
|
||||
+ buf.AudioBytes = 22050 * fmt.nBlockAlign;
|
||||
+ buf.pAudioData = HeapAlloc(GetProcessHeap(), 0, buf.AudioBytes);
|
||||
+ fill_buf((float*)buf.pAudioData, &fmt, 440, 22050);
|
||||
+
|
||||
+ hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
|
||||
+ ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);
|
||||
+
|
||||
+ hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
|
||||
+ ok(hr == S_OK, "Start failed: %08x\n", hr);
|
||||
+
|
||||
+ XA2CALL_0(StartEngine);
|
||||
+ ok(hr == S_OK, "StartEngine failed: %08x\n", hr);
|
||||
+
|
||||
+ while(1){
|
||||
+ if(xaudio27)
|
||||
+ IXAudio27SourceVoice_GetState((IXAudio27SourceVoice*)src, &state);
|
||||
+ else
|
||||
+ IXAudio2SourceVoice_GetState(src, &state, 0);
|
||||
+ if(state.SamplesPlayed >= 2205)
|
||||
+ break;
|
||||
+ Sleep(10);
|
||||
+ }
|
||||
+
|
||||
+ hr = IXAudio2SourceVoice_Stop(src, 0, XAUDIO2_COMMIT_NOW);
|
||||
+ ok(hr == S_OK, "Stop failed: %08x\n", hr);
|
||||
+
|
||||
+ hr = IXAudio2SourceVoice_FlushSourceBuffers(src);
|
||||
+ ok(hr == S_OK, "FlushSourceBuffers failed: %08x\n", hr);
|
||||
+
|
||||
+ hr = IXAudio2SourceVoice_Start(src, 0, XAUDIO2_COMMIT_NOW);
|
||||
+ ok(hr == S_OK, "Start failed: %08x\n", hr);
|
||||
+
|
||||
+ Sleep(100);
|
||||
+
|
||||
+ hr = IXAudio2SourceVoice_SubmitSourceBuffer(src, &buf, NULL);
|
||||
+ ok(hr == S_OK, "SubmitSourceBuffer failed: %08x\n", hr);
|
||||
+
|
||||
+ if(xaudio27){
|
||||
+ IXAudio27SourceVoice_DestroyVoice((IXAudio27SourceVoice*)src);
|
||||
+ }else{
|
||||
+ IXAudio2SourceVoice_DestroyVoice(src);
|
||||
+ }
|
||||
+ IXAudio2MasteringVoice_DestroyVoice(master);
|
||||
+
|
||||
+ HeapFree(GetProcessHeap(), 0, (void*)buf.pAudioData);
|
||||
+}
|
||||
+
|
||||
static UINT32 test_DeviceDetails(IXAudio27 *xa)
|
||||
{
|
||||
HRESULT hr;
|
||||
@@ -1136,6 +1212,7 @@ START_TEST(xaudio2)
|
||||
test_buffer_callbacks((IXAudio2*)xa27);
|
||||
test_looping((IXAudio2*)xa27);
|
||||
test_submix((IXAudio2*)xa27);
|
||||
+ test_flush((IXAudio2*)xa27);
|
||||
}else
|
||||
skip("No audio devices available\n");
|
||||
|
||||
@@ -1159,6 +1236,7 @@ START_TEST(xaudio2)
|
||||
test_buffer_callbacks(xa);
|
||||
test_looping(xa);
|
||||
test_submix(xa);
|
||||
+ test_flush(xa);
|
||||
}else
|
||||
skip("No audio devices available\n");
|
||||
|
||||
diff --git a/dlls/xaudio2_7/xaudio_dll.c b/dlls/xaudio2_7/xaudio_dll.c
|
||||
index b2a5e3b..8465a67 100644
|
||||
--- a/dlls/xaudio2_7/xaudio_dll.c
|
||||
+++ b/dlls/xaudio2_7/xaudio_dll.c
|
||||
@@ -414,6 +414,7 @@ static void WINAPI XA2SRC_DestroyVoice(IXAudio2SourceVoice *iface)
|
||||
This->nbufs = 0;
|
||||
This->first_buf = 0;
|
||||
This->cur_buf = 0;
|
||||
+ This->abandoned_albufs = 0;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
}
|
||||
@@ -438,11 +439,17 @@ static HRESULT WINAPI XA2SRC_Stop(IXAudio2SourceVoice *iface, UINT32 Flags,
|
||||
UINT32 OperationSet)
|
||||
{
|
||||
XA2SourceImpl *This = impl_from_IXAudio2SourceVoice(iface);
|
||||
+ ALint bufs;
|
||||
|
||||
TRACE("%p, 0x%x, 0x%x\n", This, Flags, OperationSet);
|
||||
|
||||
+ palcSetThreadContext(This->xa2->al_ctx);
|
||||
+
|
||||
EnterCriticalSection(&This->lock);
|
||||
|
||||
+ alGetSourcei(This->al_src, AL_BUFFERS_QUEUED, &bufs);
|
||||
+ This->abandoned_albufs = bufs;
|
||||
+
|
||||
This->running = FALSE;
|
||||
|
||||
LeaveCriticalSection(&This->lock);
|
||||
@@ -2252,10 +2259,24 @@ static void update_source_state(XA2SourceImpl *src)
|
||||
|
||||
alGetSourcei(src->al_src, AL_BUFFERS_PROCESSED, &processed);
|
||||
|
||||
+ if(processed > 0 && src->abandoned_albufs > 0)
|
||||
+ {
|
||||
+ ALuint al_buffers[XAUDIO2_MAX_QUEUED_BUFFERS];
|
||||
+ ALint abandoned = min(processed, src->abandoned_albufs);
|
||||
+
|
||||
+ alSourceUnqueueBuffers(src->al_src, abandoned, al_buffers);
|
||||
+ src->abandoned_albufs -= abandoned;
|
||||
+ processed -= abandoned;
|
||||
+ }
|
||||
+
|
||||
+ if(!src->running)
|
||||
+ return;
|
||||
+
|
||||
if(processed > 0){
|
||||
ALuint al_buffers[XAUDIO2_MAX_QUEUED_BUFFERS];
|
||||
|
||||
alSourceUnqueueBuffers(src->al_src, processed, al_buffers);
|
||||
+
|
||||
src->first_al_buf += processed;
|
||||
src->first_al_buf %= XAUDIO2_MAX_QUEUED_BUFFERS;
|
||||
src->al_bufs_used -= processed;
|
||||
@@ -2367,12 +2388,12 @@ static void do_engine_tick(IXAudio2Impl *This)
|
||||
|
||||
EnterCriticalSection(&src->lock);
|
||||
|
||||
- if(!src->in_use || !src->running){
|
||||
+ if(!src->in_use){
|
||||
LeaveCriticalSection(&src->lock);
|
||||
continue;
|
||||
}
|
||||
|
||||
- if(src->cb){
|
||||
+ if(src->cb && This->running){
|
||||
#if XAUDIO2_VER == 0
|
||||
IXAudio20VoiceCallback_OnVoiceProcessingPassStart((IXAudio20VoiceCallback*)src->cb);
|
||||
#else
|
||||
@@ -2386,12 +2407,14 @@ static void do_engine_tick(IXAudio2Impl *This)
|
||||
|
||||
update_source_state(src);
|
||||
|
||||
- alGetSourcei(src->al_src, AL_SOURCE_STATE, &st);
|
||||
- if(st != AL_PLAYING)
|
||||
- alSourcePlay(src->al_src);
|
||||
+ if(This->running){
|
||||
+ alGetSourcei(src->al_src, AL_SOURCE_STATE, &st);
|
||||
+ if(st != AL_PLAYING)
|
||||
+ alSourcePlay(src->al_src);
|
||||
|
||||
- if(src->cb)
|
||||
- IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(src->cb);
|
||||
+ if(src->cb)
|
||||
+ IXAudio2VoiceCallback_OnVoiceProcessingPassEnd(src->cb);
|
||||
+ }
|
||||
|
||||
LeaveCriticalSection(&src->lock);
|
||||
}
|
||||
diff --git a/dlls/xaudio2_7/xaudio_private.h b/dlls/xaudio2_7/xaudio_private.h
|
||||
index f28a0ae..1a4aa08 100644
|
||||
--- a/dlls/xaudio2_7/xaudio_private.h
|
||||
+++ b/dlls/xaudio2_7/xaudio_private.h
|
||||
@@ -81,7 +81,7 @@ typedef struct _XA2SourceImpl {
|
||||
/* most cases will only need about 4 AL buffers, but some corner cases
|
||||
* could require up to MAX_QUEUED_BUFFERS */
|
||||
ALuint al_bufs[XAUDIO2_MAX_QUEUED_BUFFERS];
|
||||
- DWORD first_al_buf, al_bufs_used;
|
||||
+ DWORD first_al_buf, al_bufs_used, abandoned_albufs;
|
||||
|
||||
struct list entry;
|
||||
} XA2SourceImpl;
|
||||
--
|
||||
2.9.0
|
||||
|
1
patches/xaudio2_7-Abandon_Albufs/definition
Normal file
1
patches/xaudio2_7-Abandon_Albufs/definition
Normal file
@ -0,0 +1 @@
|
||||
Fixes: [40963] Ignore queued xaudio2 AL buffers after Stop
|
Loading…
Reference in New Issue
Block a user