From 3f1498fc6c7c721e577049a41717ce09d9f889e5 Mon Sep 17 00:00:00 2001 From: Robert Reif Date: Fri, 14 Nov 2003 21:03:24 +0000 Subject: [PATCH] Fixes more use before set races. Work around for queue reordering feature. Stop recording on reset. Better debug info. Dsound callback capture state fix. --- dlls/dsound/capture.c | 44 ++++++++++++++++++++---------- dlls/winmm/wineoss/audio.c | 68 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 91 insertions(+), 21 deletions(-) diff --git a/dlls/dsound/capture.c b/dlls/dsound/capture.c index a7a46dab6e2..4b3f9346337 100644 --- a/dlls/dsound/capture.c +++ b/dlls/dsound/capture.c @@ -81,6 +81,13 @@ static ICOM_VTABLE(IDirectSoundFullDuplex) dsfdvt; static IDirectSoundCaptureImpl* dsound_capture = NULL; +static const char * captureStateString[] = { + "STATE_STOPPED", + "STATE_STARTING", + "STATE_CAPTURING", + "STATE_STOPPING" +}; + /*************************************************************************** * DirectSoundCaptureCreate [DSOUND.6] * @@ -314,7 +321,8 @@ DSOUND_capture_callback( if (msg == MM_WIM_DATA) { EnterCriticalSection( &(This->lock) ); - TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%ld, old This->index=%d\n",This->state,This->index); + TRACE("DirectSoundCapture msg=MM_WIM_DATA, old This->state=%s, old This->index=%d\n", + captureStateString[This->state],This->index); if (This->state != STATE_STOPPED) { int index = This->index; if (This->state == STATE_STARTING) { @@ -337,10 +345,14 @@ DSOUND_capture_callback( if (This->state == STATE_CAPTURING) { waveInPrepareHeader(hwi,&(This->pwave[index]),sizeof(WAVEHDR)); waveInAddBuffer(hwi, &(This->pwave[index]), sizeof(WAVEHDR)); - } + } else if (This->state == STATE_STOPPING) { + TRACE("stopping\n"); + This->state = STATE_STOPPED; + } } } - TRACE("DirectSoundCapture new This->state=%ld, new This->index=%d\n",This->state,This->index); + TRACE("DirectSoundCapture new This->state=%s, new This->index=%d\n", + captureStateString[This->state],This->index); LeaveCriticalSection( &(This->lock) ); } @@ -408,15 +420,15 @@ IDirectSoundCaptureImpl_Release( LPDIRECTSOUNDCAPTURE iface ) if ( uRef == 0 ) { TRACE("deleting object\n"); - if (This->capture_buffer) - IDirectSoundCaptureBufferImpl_Release( - (LPDIRECTSOUNDCAPTUREBUFFER8) This->capture_buffer); - if (This->driver) { IDsCaptureDriver_Close(This->driver); IDsCaptureDriver_Release(This->driver); } + if (This->capture_buffer) + IDirectSoundCaptureBufferImpl_Release( + (LPDIRECTSOUNDCAPTUREBUFFER8) This->capture_buffer); + if (This->pwfx) HeapFree(GetProcessHeap(), 0, This->pwfx); @@ -1094,7 +1106,7 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition( } } else if (This->dsound->hwi) { EnterCriticalSection(&(This->dsound->lock)); - TRACE("old This->dsound->state=%ld\n",This->dsound->state); + TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->state]); if (lpdwCapturePosition) { MMTIME mtime; mtime.wType = TIME_BYTES; @@ -1113,7 +1125,7 @@ IDirectSoundCaptureBufferImpl_GetCurrentPosition( } *lpdwReadPosition = This->dsound->read_position; } - TRACE("new This->dsound->state=%ld\n",This->dsound->state); + TRACE("new This->dsound->state=%s\n",captureStateString[This->dsound->state]); LeaveCriticalSection(&(This->dsound->lock)); if (lpdwCapturePosition) TRACE("*lpdwCapturePosition=%ld\n",*lpdwCapturePosition); if (lpdwReadPosition) TRACE("*lpdwReadPosition=%ld\n",*lpdwReadPosition); @@ -1193,14 +1205,16 @@ IDirectSoundCaptureBufferImpl_GetStatus( *lpdwStatus = 0; EnterCriticalSection(&(This->dsound->lock)); - TRACE("old This->dsound->state=%ld, old lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus); + TRACE("old This->dsound->state=%s, old lpdwStatus=%08lx\n", + captureStateString[This->dsound->state],*lpdwStatus); if ((This->dsound->state == STATE_STARTING) || (This->dsound->state == STATE_CAPTURING)) { *lpdwStatus |= DSCBSTATUS_CAPTURING; if (This->flags & DSCBSTART_LOOPING) *lpdwStatus |= DSCBSTATUS_LOOPING; } - TRACE("new This->dsound->state=%ld, new lpdwStatus=%08lx\n",This->dsound->state,*lpdwStatus); + TRACE("new This->dsound->state=%s, new lpdwStatus=%08lx\n", + captureStateString[This->dsound->state],*lpdwStatus); LeaveCriticalSection(&(This->dsound->lock)); TRACE("status=%lx\n", *lpdwStatus); @@ -1318,12 +1332,12 @@ IDirectSoundCaptureBufferImpl_Start( EnterCriticalSection(&(This->dsound->lock)); This->flags = dwFlags; - TRACE("old This->dsound->state=%ld\n",This->dsound->state); + TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->state]); if (This->dsound->state == STATE_STOPPED) This->dsound->state = STATE_STARTING; else if (This->dsound->state == STATE_STOPPING) This->dsound->state = STATE_CAPTURING; - TRACE("new This->dsound->state=%ld\n",This->dsound->state); + TRACE("new This->dsound->state=%s\n",captureStateString[This->dsound->state]); LeaveCriticalSection(&(This->dsound->lock)); @@ -1455,12 +1469,12 @@ IDirectSoundCaptureBufferImpl_Stop( LPDIRECTSOUNDCAPTUREBUFFER8 iface ) EnterCriticalSection(&(This->dsound->lock)); - TRACE("old This->dsound->state=%ld\n",This->dsound->state); + TRACE("old This->dsound->state=%s\n",captureStateString[This->dsound->state]); if (This->dsound->state == STATE_CAPTURING) This->dsound->state = STATE_STOPPING; else if (This->dsound->state == STATE_STARTING) This->dsound->state = STATE_STOPPED; - TRACE("new This->dsound->state=%ld\n",This->dsound->state); + TRACE("new This->dsound->state=%s\n",captureStateString[This->dsound->state]); LeaveCriticalSection(&(This->dsound->lock)); diff --git a/dlls/winmm/wineoss/audio.c b/dlls/winmm/wineoss/audio.c index 1d209838abd..cf64fd3a0ca 100644 --- a/dlls/winmm/wineoss/audio.c +++ b/dlls/winmm/wineoss/audio.c @@ -1011,7 +1011,9 @@ static int OSS_PeekRingMessage(OSS_MSG_RING* omr, */ static DWORD wodNotifyClient(WINE_WAVEOUT* wwo, WORD wMsg, DWORD dwParam1, DWORD dwParam2) { - TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2); + TRACE("wMsg = 0x%04x (%s) dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, + wMsg == WOM_OPEN ? "WOM_OPEN" : wMsg == WOM_CLOSE ? "WOM_CLOSE" : + wMsg == WOM_DONE ? "WOM_DONE" : "Unknown", dwParam1, dwParam2); switch (wMsg) { case WOM_OPEN: @@ -1178,7 +1180,7 @@ static BOOL wodPlayer_WriteMaxFrags(WINE_WAVEOUT* wwo, DWORD* bytes) } *bytes -= written; wwo->dwWrittenTotal += written; - + TRACE("dwWrittenTotal=%lu\n", wwo->dwWrittenTotal); return ret; } @@ -2555,7 +2557,9 @@ static DWORD wodDsGuid(UINT wDevID, LPGUID pGuid) */ static DWORD widNotifyClient(WINE_WAVEIN* wwi, WORD wMsg, DWORD dwParam1, DWORD dwParam2) { - TRACE("wMsg = 0x%04x dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, dwParam1, dwParam2); + TRACE("wMsg = 0x%04x (%s) dwParm1 = %04lX dwParam2 = %04lX\n", wMsg, + wMsg == WIM_OPEN ? "WIM_OPEN" : wMsg == WIM_CLOSE ? "WIM_CLOSE" : + wMsg == WIM_DATA ? "WIM_DATA" : "Unknown", dwParam1, dwParam2); switch (wMsg) { case WIM_OPEN: @@ -2595,6 +2599,34 @@ static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSA lpCaps, DWORD dwSize) } /************************************************************************** + * widRecorder_ReadHeaders [internal] + */ +static void widRecorder_ReadHeaders(WINE_WAVEIN * wwi) +{ + enum win_wm_message tmp_msg; + DWORD tmp_param; + HANDLE tmp_ev; + WAVEHDR* lpWaveHdr; + + while (OSS_RetrieveRingMessage(&wwi->msgRing, &tmp_msg, &tmp_param, &tmp_ev)) { + if (tmp_msg == WINE_WM_HEADER) { + LPWAVEHDR* wh; + lpWaveHdr = (LPWAVEHDR)tmp_param; + lpWaveHdr->lpNext = 0; + + if (wwi->lpQueuePtr == 0) + wwi->lpQueuePtr = lpWaveHdr; + else { + for (wh = &(wwi->lpQueuePtr); *wh; wh = &((*wh)->lpNext)); + *wh = lpWaveHdr; + } + } else { + ERR("should only have headers left\n"); + } + } +} + +/************************************************************************** * widRecorder [internal] */ static DWORD CALLBACK widRecorder(LPVOID pmt) @@ -2677,8 +2709,9 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; lpWaveHdr->dwFlags |= WHDR_DONE; + wwi->lpQueuePtr = lpNext; widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); - lpWaveHdr = wwi->lpQueuePtr = lpNext; + lpWaveHdr = lpNext; } } } @@ -2816,6 +2849,10 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno)); } } + + /* read any headers in queue */ + widRecorder_ReadHeaders(wwi); + /* return current buffer to app */ lpWaveHdr = wwi->lpQueuePtr; if (lpWaveHdr) @@ -2824,24 +2861,42 @@ static DWORD CALLBACK widRecorder(LPVOID pmt) TRACE("stop %p %p\n", lpWaveHdr, lpWaveHdr->lpNext); lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; lpWaveHdr->dwFlags |= WHDR_DONE; - widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); wwi->lpQueuePtr = lpNext; + widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); } } wwi->state = WINE_WS_STOPPED; SetEvent(ev); break; case WINE_WM_RESETTING: + if (wwi->state != WINE_WS_STOPPED) + { + if (wwi->ossdev->bTriggerSupport) + { + /* stop the recording */ + wwi->ossdev->bInputEnabled = FALSE; + enable = getEnables(wwi->ossdev); + if (ioctl(wwi->ossdev->fd, SNDCTL_DSP_SETTRIGGER, &enable) < 0) { + wwi->ossdev->bInputEnabled = FALSE; + ERR("ioctl(%s, SNDCTL_DSP_SETTRIGGER) failed (%s)\n", wwi->ossdev->dev_name, strerror(errno)); + } + } + } wwi->state = WINE_WS_STOPPED; wwi->dwTotalRecorded = 0; + + /* read any headers in queue */ + widRecorder_ReadHeaders(wwi); + /* return all buffers to the app */ for (lpWaveHdr = wwi->lpQueuePtr; lpWaveHdr; lpWaveHdr = lpWaveHdr->lpNext) { TRACE("reset %p %p\n", lpWaveHdr, lpWaveHdr->lpNext); lpWaveHdr->dwFlags &= ~WHDR_INQUEUE; lpWaveHdr->dwFlags |= WHDR_DONE; - + wwi->lpQueuePtr = lpWaveHdr->lpNext; widNotifyClient(wwi, WIM_DATA, (DWORD)lpWaveHdr, 0); } + wwi->lpQueuePtr = NULL; SetEvent(ev); break; @@ -2978,6 +3033,7 @@ static DWORD widOpen(WORD wDevID, LPWAVEOPENDESC lpDesc, DWORD dwFlags) } wwi->dwFragmentSize = fragment_size; + TRACE("dwFragmentSize=%lu\n", wwi->dwFragmentSize); TRACE("wBitsPerSample=%u, nAvgBytesPerSec=%lu, nSamplesPerSec=%lu, nChannels=%u nBlockAlign=%u!\n", wwi->format.wBitsPerSample, wwi->format.wf.nAvgBytesPerSec, wwi->format.wf.nSamplesPerSec, wwi->format.wf.nChannels, -- 2.11.4.GIT