mirror of
https://github.com/reactos/wine.git
synced 2025-02-22 13:53:38 +00:00
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:
parent
136fa03fbf
commit
3f1498fc6c
@ -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));
|
||||
|
||||
|
@ -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,
|
||||
|
Loading…
x
Reference in New Issue
Block a user