Fixes more use before set races.

Work around for queue reordering feature.
Stop recording on reset.
Better debug info.
Dsound callback capture state fix.
This commit is contained in:
Robert Reif 2003-11-14 21:03:24 +00:00 committed by Alexandre Julliard
parent 136fa03fbf
commit 3f1498fc6c
2 changed files with 91 additions and 21 deletions

View file

@ -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));

View file

@ -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:
@ -2594,6 +2598,34 @@ static DWORD widGetDevCaps(WORD wDevID, LPWAVEINCAPSA lpCaps, DWORD dwSize)
return MMSYSERR_NOERROR;
}
/**************************************************************************
* 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]
*/
@ -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,