From: Martin Fleisz Date: Fri, 17 Jan 2020 12:02:31 +0000 (+0100) Subject: rdpsnd: Add synchronization to winmm backend X-Git-Tag: 2.0.0~171 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=706e32982ecafce069d34c8b2015caac0bb3038d;p=platform%2Fupstream%2Ffreerdp.git rdpsnd: Add synchronization to winmm backend --- diff --git a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c index c9ce8e6..f9fad9b 100644 --- a/channels/rdpsnd/client/winmm/rdpsnd_winmm.c +++ b/channels/rdpsnd/client/winmm/rdpsnd_winmm.c @@ -54,6 +54,7 @@ struct rdpsnd_winmm_plugin UINT32 latency; HANDLE hThread; DWORD threadId; + CRITICAL_SECTION cs; }; static BOOL rdpsnd_winmm_convert_format(const AUDIO_FORMAT* in, WAVEFORMATEX* out) @@ -96,6 +97,7 @@ static BOOL rdpsnd_winmm_set_format(rdpsndDevicePlugin* device, const AUDIO_FORM static DWORD WINAPI waveOutProc(LPVOID lpParameter) { MSG msg; + rdpsndWinmmPlugin* winmm = (rdpsndWinmmPlugin*)lpParameter; while (GetMessage(&msg, NULL, 0, 0)) { if (msg.message == MM_WOM_CLOSE) @@ -107,7 +109,9 @@ static DWORD WINAPI waveOutProc(LPVOID lpParameter) { /* free buffer */ LPWAVEHDR waveHdr = (LPWAVEHDR)msg.lParam; + EnterCriticalSection(&winmm->cs); waveOutUnprepareHeader((HWAVEOUT)msg.wParam, waveHdr, sizeof(WAVEHDR)); + LeaveCriticalSection(&winmm->cs); free(waveHdr->lpData); free(waveHdr); } @@ -128,7 +132,7 @@ static BOOL rdpsnd_winmm_open(rdpsndDevicePlugin* device, const AUDIO_FORMAT* fo if (!rdpsnd_winmm_set_format(device, format, latency)) return FALSE; - winmm->hThread = CreateThread(NULL, 0, waveOutProc, NULL, 0, &winmm->threadId); + winmm->hThread = CreateThread(NULL, 0, waveOutProc, winmm, 0, &winmm->threadId); if (!winmm->hThread) { WLog_Print(winmm->log, WLOG_ERROR, "CreateThread failed: %" PRIu32 "", GetLastError()); @@ -162,6 +166,8 @@ static void rdpsnd_winmm_close(rdpsndDevicePlugin* device) if (winmm->hWaveOut) { + EnterCriticalSection(&winmm->cs); + mmResult = waveOutReset(winmm->hWaveOut); if (mmResult != MMSYSERR_NOERROR) WLog_Print(winmm->log, WLOG_ERROR, "waveOutReset failure: %" PRIu32 "", mmResult); @@ -170,6 +176,8 @@ static void rdpsnd_winmm_close(rdpsndDevicePlugin* device) if (mmResult != MMSYSERR_NOERROR) WLog_Print(winmm->log, WLOG_ERROR, "waveOutClose failure: %" PRIu32 "", mmResult); + LeaveCriticalSection(&winmm->cs); + winmm->hWaveOut = NULL; } @@ -188,6 +196,7 @@ static void rdpsnd_winmm_free(rdpsndDevicePlugin* device) if (winmm) { rdpsnd_winmm_close(device); + DeleteCriticalSection(&winmm->cs); free(winmm); } } @@ -269,11 +278,13 @@ static UINT rdpsnd_winmm_play(rdpsndDevicePlugin* device, const BYTE* data, size memcpy(lpWaveHdr->lpData, data, size); lpWaveHdr->dwBufferLength = (DWORD)size; + EnterCriticalSection(&winmm->cs); + mmResult = waveOutPrepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); if (mmResult != MMSYSERR_NOERROR) { WLog_Print(winmm->log, WLOG_ERROR, "waveOutPrepareHeader failure: %" PRIu32 "", mmResult); - goto fail; + goto failCS; } mmResult = waveOutWrite(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); @@ -281,10 +292,13 @@ static UINT rdpsnd_winmm_play(rdpsndDevicePlugin* device, const BYTE* data, size { WLog_Print(winmm->log, WLOG_ERROR, "waveOutWrite failure: %" PRIu32 "", mmResult); waveOutUnprepareHeader(winmm->hWaveOut, lpWaveHdr, sizeof(WAVEHDR)); - goto fail; + goto failCS; } + LeaveCriticalSection(&winmm->cs); return winmm->latency; +failCS: + LeaveCriticalSection(&winmm->cs); fail: if (lpWaveHdr) free(lpWaveHdr->lpData); @@ -332,6 +346,7 @@ UINT freerdp_rdpsnd_client_subsystem_entry(PFREERDP_RDPSND_DEVICE_ENTRY_POINTS p winmm->device.Close = rdpsnd_winmm_close; winmm->device.Free = rdpsnd_winmm_free; winmm->log = WLog_Get(TAG); + InitializeCriticalSection(&winmm->cs); args = pEntryPoints->args; rdpsnd_winmm_parse_addin_args((rdpsndDevicePlugin*)winmm, args);