Jörg Höhle : winmm: Mark headers WHDR_DONE at the last possible time.
Module: wine Branch: master Commit: 3ba00cf538cc07d8e36ae82d43a29247cb37a299 URL: http://source.winehq.org/git/wine.git/?a=commit;h=3ba00cf538cc07d8e36ae82d43... Author: Jörg Höhle <hoehle(a)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; }
participants (1)
-
Alexandre Julliard