Module: wine Branch: master Commit: 3ba00cf538cc07d8e36ae82d43a29247cb37a299 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3ba00cf538cc07d8e36ae82d43...
Author: Jörg Höhle hoehle@users.sourceforge.net Date: Thu Sep 22 21:43:42 2011 +0200
winmm: Mark headers WHDR_DONE at the last possible time.
---
dlls/winmm/waveform.c | 45 +++++++++++++++++++++++++++------------------ 1 files changed, 27 insertions(+), 18 deletions(-)
diff --git a/dlls/winmm/waveform.c b/dlls/winmm/waveform.c index cf6f52e..0aa6320 100644 --- a/dlls/winmm/waveform.c +++ b/dlls/winmm/waveform.c @@ -1231,32 +1231,30 @@ static UINT32 WINMM_HeaderLenFrames(WINMM_Device *device, WAVEHDR *header) static WAVEHDR *WOD_MarkDoneHeaders(WINMM_Device *device) { HRESULT hr; - WAVEHDR *queue, *first = device->first; + WAVEHDR *first = device->first, *queue = first, *last = NULL; UINT64 clock_freq, clock_pos, clock_frames; UINT32 nloops, queue_frames = 0;
hr = IAudioClock_GetFrequency(device->clock, &clock_freq); if(FAILED(hr)){ ERR("GetFrequency failed: %08x\n", hr); - return first; + return NULL; }
hr = IAudioClock_GetPosition(device->clock, &clock_pos, NULL); if(FAILED(hr)){ ERR("GetPosition failed: %08x\n", hr); - return first; + return NULL; }
clock_frames = (clock_pos / (double)clock_freq) * device->samples_per_sec;
- first = queue = device->first; nloops = device->loop_counter; while(queue && (queue_frames += WINMM_HeaderLenFrames(device, queue)) <= clock_frames - device->last_clock_pos){ if(!nloops){ - device->first->dwFlags &= ~WHDR_INQUEUE; - device->first->dwFlags |= WHDR_DONE; + last = queue; device->last_clock_pos += queue_frames; queue_frames = 0; queue = device->first = queue->lpNext; @@ -1273,7 +1271,11 @@ static WAVEHDR *WOD_MarkDoneHeaders(WINMM_Device *device) } }
- return first; + if(last){ + last->lpNext = NULL; + return first; + }else + return NULL; }
static void WOD_PushData(WINMM_Device *device) @@ -1426,8 +1428,10 @@ exit:
LeaveCriticalSection(&device->lock);
- while(first && (first->dwFlags & WHDR_DONE)){ + while(first){ WAVEHDR *next = first->lpNext; + first->dwFlags &= ~WHDR_INQUEUE; + first->dwFlags |= WHDR_DONE; WINMM_NotifyClient(&cb_info, WOM_DONE, (DWORD_PTR)first, 0); first = next; } @@ -1535,7 +1539,7 @@ static void WID_PullACMData(WINMM_Device *device) static void WID_PullData(WINMM_Device *device) { WINMM_CBInfo cb_info; - WAVEHDR *queue, *first = NULL; + WAVEHDR *queue, *first = NULL, *last = NULL; HRESULT hr;
TRACE("(%p)\n", device->handle); @@ -1588,8 +1592,7 @@ static void WID_PullData(WINMM_Device *device)
if(queue->dwBufferLength - queue->dwBytesRecorded < device->bytes_per_frame){ - queue->dwFlags &= ~WHDR_INQUEUE; - queue->dwFlags |= WHDR_DONE; + last = queue; device->first = queue = queue->lpNext; }
@@ -1606,10 +1609,15 @@ exit:
LeaveCriticalSection(&device->lock);
- while(first && (first->dwFlags & WHDR_DONE)){ - WAVEHDR *next = first->lpNext; - WINMM_NotifyClient(&cb_info, WIM_DATA, (DWORD_PTR)first, 0); - first = next; + if(last){ + last->lpNext = NULL; + while(first){ + WAVEHDR *next = first->lpNext; + first->dwFlags &= ~WHDR_INQUEUE; + first->dwFlags |= WHDR_DONE; + WINMM_NotifyClient(&cb_info, WIM_DATA, (DWORD_PTR)first, 0); + first = next; + } } }
@@ -3075,8 +3083,6 @@ UINT WINAPI waveInStop(HWAVEIN hWaveIn) buf = device->first; if(buf && buf->dwBytesRecorded > 0){ device->first = buf->lpNext; - buf->dwFlags &= ~WHDR_INQUEUE; - buf->dwFlags |= WHDR_DONE; }else buf = NULL;
@@ -3084,8 +3090,11 @@ UINT WINAPI waveInStop(HWAVEIN hWaveIn)
LeaveCriticalSection(&device->lock);
- if(buf) + if(buf){ + buf->dwFlags &= ~WHDR_INQUEUE; + buf->dwFlags |= WHDR_DONE; WINMM_NotifyClient(&cb_info, WIM_DATA, (DWORD_PTR)buf, 0); + }
return MMSYSERR_NOERROR; }