diff --git a/channels/audin/server/audin.c b/channels/audin/server/audin.c index 8d5a886f4..0a4773e8c 100644 --- a/channels/audin/server/audin.c +++ b/channels/audin/server/audin.c @@ -82,8 +82,9 @@ static UINT audin_server_select_format(audin_server_context* context, } context->selected_client_format = client_format_index; + if (!freerdp_dsp_context_reset(audin->dsp_context, - &audin->context.client_formats[client_format_index])) + &audin->context.client_formats[client_format_index])) { WLog_ERR(TAG, "Failed to reset dsp context format!"); return ERROR_INTERNAL_ERROR; @@ -627,6 +628,16 @@ static BOOL audin_server_open(audin_server_context* context) return FALSE; } +static BOOL audin_server_is_open(audin_server_context* context) +{ + audin_server* audin = (audin_server*) context; + + if (!audin) + return FALSE; + + return audin->thread != NULL; +} + static BOOL audin_server_close(audin_server_context* context) { audin_server* audin = (audin_server*) context; @@ -673,6 +684,7 @@ audin_server_context* audin_server_context_new(HANDLE vcm) audin->context.frames_per_packet = 4096; audin->context.SelectFormat = audin_server_select_format; audin->context.Open = audin_server_open; + audin->context.IsOpen = audin_server_is_open; audin->context.Close = audin_server_close; audin->dsp_context = freerdp_dsp_context_new(FALSE); diff --git a/include/freerdp/server/audin.h b/include/freerdp/server/audin.h index a10c99773..10c7a88c6 100644 --- a/include/freerdp/server/audin.h +++ b/include/freerdp/server/audin.h @@ -28,13 +28,15 @@ typedef struct _audin_server_context audin_server_context; -typedef UINT (*psAudinServerSelectFormat)(audin_server_context* context, int client_format_index); +typedef UINT(*psAudinServerSelectFormat)(audin_server_context* context, int client_format_index); typedef BOOL (*psAudinServerOpen)(audin_server_context* context); +typedef BOOL (*psAudinServerIsOpen)(audin_server_context* context); typedef BOOL (*psAudinServerClose)(audin_server_context* context); -typedef UINT (*psAudinServerOpening)(audin_server_context* context); -typedef UINT (*psAudinServerOpenResult)(audin_server_context* context, UINT32 result); -typedef UINT (*psAudinServerReceiveSamples)(audin_server_context* context, const void* buf, int nframes); +typedef UINT(*psAudinServerOpening)(audin_server_context* context); +typedef UINT(*psAudinServerOpenResult)(audin_server_context* context, UINT32 result); +typedef UINT(*psAudinServerReceiveSamples)(audin_server_context* context, const void* buf, + int nframes); struct _audin_server_context { @@ -68,6 +70,9 @@ struct _audin_server_context * Open the audio input stream. */ psAudinServerOpen Open; + + psAudinServerIsOpen IsOpen; + /** * Close the audio stream. */ diff --git a/server/shadow/shadow_client.c b/server/shadow/shadow_client.c index 94337c95b..6c421a94b 100644 --- a/server/shadow/shadow_client.c +++ b/server/shadow/shadow_client.c @@ -1655,7 +1655,7 @@ static DWORD WINAPI shadow_client_thread(LPVOID arg) if (tmp == 0) { WLog_ERR(TAG, "Failed to get FreeRDP transport event handles"); - break; + goto fail; } nCount += tmp; @@ -1665,7 +1665,7 @@ static DWORD WINAPI shadow_client_thread(LPVOID arg) status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE); if (status == WAIT_FAILED) - break; + goto fail; if (WaitForSingleObject(UpdateEvent, 0) == WAIT_OBJECT_0) { @@ -1720,41 +1720,57 @@ static DWORD WINAPI shadow_client_thread(LPVOID arg) if (!peer->CheckFileDescriptor(peer)) { WLog_ERR(TAG, "Failed to check FreeRDP file descriptor"); - break; + goto fail; } else { if (WTSVirtualChannelManagerIsChannelJoined(client->vcm, "drdynvc")) { - /* Dynamic channel status may have been changed after processing */ - if (WTSVirtualChannelManagerGetDrdynvcState(client->vcm) == DRDYNVC_STATE_NONE) + switch (WTSVirtualChannelManagerGetDrdynvcState(client->vcm)) { - /* Call this routine to Initialize drdynvc channel */ - if (!WTSVirtualChannelManagerCheckFileDescriptor(client->vcm)) - { - WLog_ERR(TAG, "Failed to initialize drdynvc channel"); - break; - } - } - else if (WTSVirtualChannelManagerGetDrdynvcState(client->vcm) == - DRDYNVC_STATE_READY) - { - /* Init RDPGFX dynamic channel */ - if (settings->SupportGraphicsPipeline && client->rdpgfx && - !gfxstatus.gfxOpened) - { - client->rdpgfx->FrameAcknowledge = shadow_client_rdpgfx_frame_acknowledge; - client->rdpgfx->CapsAdvertise = shadow_client_rdpgfx_caps_advertise; + /* Dynamic channel status may have been changed after processing */ + case DRDYNVC_STATE_NONE: - if (!client->rdpgfx->Open(client->rdpgfx)) + /* Call this routine to Initialize drdynvc channel */ + if (!WTSVirtualChannelManagerCheckFileDescriptor(client->vcm)) { - WLog_WARN(TAG, "Failed to open GraphicsPipeline"); - settings->SupportGraphicsPipeline = FALSE; + WLog_ERR(TAG, "Failed to initialize drdynvc channel"); + goto fail; } - gfxstatus.gfxOpened = TRUE; - WLog_INFO(TAG, "Gfx Pipeline Opened"); - } + break; + + case DRDYNVC_STATE_READY: + if (client->audin && !IFCALLRESULT(TRUE, client->audin->IsOpen, client->audin)) + { + if (!IFCALLRESULT(FALSE, client->audin->Open, client->audin)) + { + WLog_ERR(TAG, "Failed to initialize audin channel"); + goto fail; + } + } + + /* Init RDPGFX dynamic channel */ + if (settings->SupportGraphicsPipeline && client->rdpgfx && + !gfxstatus.gfxOpened) + { + client->rdpgfx->FrameAcknowledge = shadow_client_rdpgfx_frame_acknowledge; + client->rdpgfx->CapsAdvertise = shadow_client_rdpgfx_caps_advertise; + + if (!client->rdpgfx->Open(client->rdpgfx)) + { + WLog_WARN(TAG, "Failed to open GraphicsPipeline"); + settings->SupportGraphicsPipeline = FALSE; + } + + gfxstatus.gfxOpened = TRUE; + WLog_INFO(TAG, "Gfx Pipeline Opened"); + } + + break; + + default: + break; } } } @@ -1764,7 +1780,7 @@ static DWORD WINAPI shadow_client_thread(LPVOID arg) if (!WTSVirtualChannelManagerCheckFileDescriptor(client->vcm)) { WLog_ERR(TAG, "WTSVirtualChannelManagerCheckFileDescriptor failure"); - break; + goto fail; } } @@ -1817,7 +1833,7 @@ static DWORD WINAPI shadow_client_thread(LPVOID arg) shadow_client_free_queued_message(&pointerPositionMsg); shadow_client_free_queued_message(&pointerAlphaMsg); shadow_client_free_queued_message(&audioVolumeMsg); - break; + goto fail; } else { @@ -1840,7 +1856,17 @@ static DWORD WINAPI shadow_client_thread(LPVOID arg) } } +fail: + /* Free channels early because we establish channels in post connect */ + if (client->audin && !IFCALLRESULT(TRUE, client->audin->IsOpen, client->audin)) + { + if (!IFCALLRESULT(FALSE, client->audin->Close, client->audin)) + { + WLog_WARN(TAG, "AUDIN shutdown failure!"); + } + } + if (gfxstatus.gfxOpened) { if (gfxstatus.gfxSurfaceCreated)