Added microphone support to shadow server.

This commit is contained in:
Armin Novak 2018-09-25 11:13:32 +02:00
parent ba69925b8d
commit dab5770fed
3 changed files with 77 additions and 34 deletions

View File

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

View File

@ -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.
*/

View File

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