On вторник, 27 апреля 2021 г. 06:23:58 +07 you wrote:
On 4/25/21 9:51 PM, Anton Baskanov wrote:
Fixes audio stuttering during video playback in multiple games (e.g. Commandos 2, Alien Nations, Dino Crisis Demo).
Can you please provide a +quartz,+strmbase,+gstreamer log that demonstrates the problem?
I've attached the log of the Commandos 2 (GOG version) first intro video playback. The relevant part is:
0154:trace:quartz:DSoundRender_SendSampleData Wrote 75500 bytes at 17108, next at 4408 - (75500/88200) 0154:trace:quartz:SystemClockImpl_GetTime clock 002D8440, time 03FBFC20, returning 1569156.542. 0154:trace:quartz:DSoundRender_SendSampleData Wrote 12700 bytes at 4408, next at 17108 - (88196/12700)
First, DSoundRender_GetWritePos reports 75500 free bytes, so we write 75500 bytes to the buffer. At this point, DSoundRender_GetWritePos must report 0 free bytes, since the buffer is full, but it reports 88196 instead, so we write another 12700 bytes, overrunning playpos.
Some time after that an underrun happens when dsound write cursor advances past our write position:
0154:fixme:quartz:DSoundRender_UpdatePositions Underrun of data occurred!
To reproduce this issue there has to be enough data to fill the buffer, i.e. the samples must be at least 1s in length.
Signed-off-by: Anton Baskanov baskanov@gmail.com
dlls/quartz/dsoundrender.c | 5 +---- dlls/quartz/tests/dsoundrender.c | 2 +- 2 files changed, 2 insertions(+), 5 deletions(-)
diff --git a/dlls/quartz/dsoundrender.c b/dlls/quartz/dsoundrender.c index 6c6732e468a..f7f0255d4ab 100644 --- a/dlls/quartz/dsoundrender.c +++ b/dlls/quartz/dsoundrender.c @@ -149,7 +149,6 @@ static void DSoundRender_UpdatePositions(struct dsound_render *This, DWORD *seqw> static HRESULT DSoundRender_GetWritePos(struct dsound_render *This,
DWORD *ret_writepos, REFERENCE_TIME write_at, DWORD *pfree, DWORD *skip)
{
WAVEFORMATEX *wfx = (WAVEFORMATEX *)This->sink.pin.mt.pbFormat;
DWORD writepos, min_writepos, playpos; REFERENCE_TIME max_lag = 50 * 10000; REFERENCE_TIME cur, writepos_t, delta_t;
@@ -212,10 +211,8 @@ static HRESULT DSoundRender_GetWritePos(struct dsound_render *This,> *ret_writepos = (min_writepos + aheadbytes) % This->buf_size;
}
end:
- if (playpos > *ret_writepos)
if (playpos >= *ret_writepos)
*pfree = playpos - *ret_writepos;
else if (playpos == *ret_writepos)
*pfree = This->buf_size - wfx->nBlockAlign; else *pfree = This->buf_size + playpos - *ret_writepos; if (time_from_pos(This, This->buf_size - *pfree) >= DSoundRenderer_Max_Fill) {>
diff --git a/dlls/quartz/tests/dsoundrender.c b/dlls/quartz/tests/dsoundrender.c index c33c074d93d..e591e1832d5 100644 --- a/dlls/quartz/tests/dsoundrender.c +++ b/dlls/quartz/tests/dsoundrender.c @@ -737,7 +737,7 @@ static HRESULT send_frame(IMemInputPin *sink)
params->sink = sink; params->sample = sample; thread = CreateThread(NULL, 0, frame_thread, params, 0, NULL);
- ret = WaitForSingleObject(thread, 500);
ret = WaitForSingleObject(thread, 2000);
todo_wine_if (ret) ok(!ret, "Wait failed.\n"); GetExitCodeThread(thread, &ret); CloseHandle(thread);