diff --git a/protocols/rdp/guac_rdpsnd/messages.c b/protocols/rdp/guac_rdpsnd/messages.c index a0e15060..b6948ca3 100644 --- a/protocols/rdp/guac_rdpsnd/messages.c +++ b/protocols/rdp/guac_rdpsnd/messages.c @@ -31,6 +31,7 @@ #include +#include "audio.h" #include "service.h" #include "messages.h" @@ -39,7 +40,7 @@ /* receives a list of server supported formats and returns a list of client supported formats */ void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* input_stream) { + audio_stream* audio, STREAM* input_stream) { uint16 wNumberOfFormats; uint16 nFormat; @@ -96,7 +97,7 @@ void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, if (format->wFormatTag == WAVE_FORMAT_PCM) { - guac_client_log_info(client, + guac_client_log_info(audio->client, "Accepted format: %i-bit PCM with %i channels at " "%i Hz", format->wBitsPerSample, @@ -143,7 +144,7 @@ void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, /* server is getting a feel of the round trip time */ void guac_rdpsnd_process_message_training(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* input_stream) { + audio_stream* audio, STREAM* input_stream) { uint16 wTimeStamp; uint16 wPackSize; @@ -165,7 +166,7 @@ void guac_rdpsnd_process_message_training(guac_rdpsndPlugin* rdpsnd, } -void guac_rdpsnd_process_message_wave_info(guac_rdpsndPlugin* rdpsnd, guac_client* client, STREAM* input_stream, uint16 BodySize) { +void guac_rdpsnd_process_message_wave_info(guac_rdpsndPlugin* rdpsnd, audio_stream* audio, STREAM* input_stream, uint16 BodySize) { uint16 wFormatNo; @@ -184,7 +185,7 @@ void guac_rdpsnd_process_message_wave_info(guac_rdpsndPlugin* rdpsnd, guac_clien /* header is not removed from data in this function */ void rdpsnd_process_message_wave(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* input_stream) { + audio_stream* audio, STREAM* input_stream) { rdpSvcPlugin* plugin = (rdpSvcPlugin*)rdpsnd; @@ -202,7 +203,7 @@ void rdpsnd_process_message_wave(guac_rdpsndPlugin* rdpsnd, buffer = stream_get_head(input_stream); size = stream_get_size(input_stream); - guac_client_log_info(client, "Got sound: %i bytes.", size); + guac_client_log_info(audio->client, "Got sound: %i bytes.", size); output_stream = stream_new(8); stream_write_uint8(output_stream, SNDC_WAVECONFIRM); @@ -217,7 +218,7 @@ void rdpsnd_process_message_wave(guac_rdpsndPlugin* rdpsnd, } void guac_rdpsnd_process_message_setvolume(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* input_stream) { + audio_stream* audio, STREAM* input_stream) { /* Ignored for now */ uint32 dwVolume; @@ -226,7 +227,7 @@ void guac_rdpsnd_process_message_setvolume(guac_rdpsndPlugin* rdpsnd, } void guac_rdpsnd_process_message_close(guac_rdpsndPlugin* rdpsnd, - guac_client* client) { + audio_stream* audio) { rdpsnd->plugin.interval_ms = 10; } diff --git a/protocols/rdp/guac_rdpsnd/messages.h b/protocols/rdp/guac_rdpsnd/messages.h index b83cdfdd..2b66f7e1 100644 --- a/protocols/rdp/guac_rdpsnd/messages.h +++ b/protocols/rdp/guac_rdpsnd/messages.h @@ -54,22 +54,22 @@ typedef struct rdpsndFormat { } rdpsndFormat; void guac_rdpsnd_process_message_formats(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* data_in); + audio_stream* audio, STREAM* data_in); void guac_rdpsnd_process_message_training(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* data_in); + audio_stream* audio, STREAM* data_in); void guac_rdpsnd_process_message_wave_info(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* data_in, uint16 BodySize); + audio_stream* audio, STREAM* data_in, uint16 BodySize); void rdpsnd_process_message_wave(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* data_in); + audio_stream* audio, STREAM* data_in); void guac_rdpsnd_process_message_setvolume(guac_rdpsndPlugin* rdpsnd, - guac_client* client, STREAM* data_in); + audio_stream* audio, STREAM* data_in); void guac_rdpsnd_process_message_close(guac_rdpsndPlugin* rdpsnd, - guac_client* client); + audio_stream* audio); #endif diff --git a/protocols/rdp/guac_rdpsnd/service.c b/protocols/rdp/guac_rdpsnd/service.c index a9752d9d..e9a92f4f 100644 --- a/protocols/rdp/guac_rdpsnd/service.c +++ b/protocols/rdp/guac_rdpsnd/service.c @@ -31,6 +31,7 @@ #include +#include "audio.h" #include "service.h" #include "messages.h" @@ -41,12 +42,12 @@ DEFINE_SVC_PLUGIN(guac_rdpsnd, "rdpsnd", void guac_rdpsnd_process_connect(rdpSvcPlugin* plugin) { - /* Get client from plugin */ - guac_client* client = (guac_client*) + /* Get audio stream from plugin */ + audio_stream* audio = (audio_stream*) plugin->channel_entry_points.pExtendedData; /* Log that sound has been loaded */ - guac_client_log_info(client, "guac_rdpsnd connected."); + guac_client_log_info(audio->client, "guac_rdpsnd connected."); } @@ -63,15 +64,15 @@ void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin, guac_rdpsndPlugin* rdpsnd = (guac_rdpsndPlugin*) plugin; - /* Get client from plugin */ - guac_client* client = (guac_client*) + /* Get audio stream from plugin */ + audio_stream* audio = (audio_stream*) plugin->channel_entry_points.pExtendedData; uint8 msgType; uint16 BodySize; if (rdpsnd->expectingWave) { - rdpsnd_process_message_wave(rdpsnd, client, input_stream); + rdpsnd_process_message_wave(rdpsnd, audio, input_stream); return; } @@ -83,23 +84,23 @@ void guac_rdpsnd_process_receive(rdpSvcPlugin* plugin, switch (msgType) { case SNDC_FORMATS: - guac_rdpsnd_process_message_formats(rdpsnd, client, input_stream); + guac_rdpsnd_process_message_formats(rdpsnd, audio, input_stream); break; case SNDC_TRAINING: - guac_rdpsnd_process_message_training(rdpsnd, client, input_stream); + guac_rdpsnd_process_message_training(rdpsnd, audio, input_stream); break; case SNDC_WAVE: - guac_rdpsnd_process_message_wave_info(rdpsnd, client, input_stream, BodySize); + guac_rdpsnd_process_message_wave_info(rdpsnd, audio, input_stream, BodySize); break; case SNDC_CLOSE: - guac_rdpsnd_process_message_close(rdpsnd, client); + guac_rdpsnd_process_message_close(rdpsnd, audio); break; case SNDC_SETVOLUME: - guac_rdpsnd_process_message_setvolume(rdpsnd, client, input_stream); + guac_rdpsnd_process_message_setvolume(rdpsnd, audio, input_stream); break; default: diff --git a/protocols/rdp/include/client.h b/protocols/rdp/include/client.h index 0c28d8fe..1fba847f 100644 --- a/protocols/rdp/include/client.h +++ b/protocols/rdp/include/client.h @@ -45,6 +45,7 @@ #include +#include "audio.h" #include "rdp_keymap.h" /** @@ -138,6 +139,11 @@ typedef struct rdp_guac_client_data { */ char* clipboard; + /** + * Audio output, if any. + */ + audio_stream* audio; + } rdp_guac_client_data; /** diff --git a/protocols/rdp/src/client.c b/protocols/rdp/src/client.c index 3bba1d23..9345933b 100644 --- a/protocols/rdp/src/client.c +++ b/protocols/rdp/src/client.c @@ -61,6 +61,9 @@ #include #include +#include "audio.h" +#include "ogg_encoder.h" + #include "client.h" #include "guac_handlers.h" #include "rdp_keymap.h" @@ -110,16 +113,43 @@ boolean rdp_freerdp_pre_connect(freerdp* instance) { rdpPointer* pointer; rdpPrimaryUpdate* primary; CLRCONV* clrconv; + int i; + + rdp_guac_client_data* guac_client_data = + (rdp_guac_client_data*) client->data; /* Load clipboard plugin */ if (freerdp_channels_load_plugin(channels, instance->settings, "cliprdr", NULL)) guac_client_log_error(client, "Failed to load cliprdr plugin."); - /* Load sound plugin */ - if (freerdp_channels_load_plugin(channels, instance->settings, - "guac_rdpsnd", client)) - guac_client_log_error(client, "Failed to load guac_rdpsnd plugin."); + /* Choose an encoding */ + for (i=0; client->info.audio_mimetypes[i] != NULL; i++) { + + const char* mimetype = client->info.audio_mimetypes[i]; + + // If Ogg is supported, done. + if (strcmp(mimetype, "audio/ogg") == 0) { + guac_client_log_info(client, "Loading Ogg Vorbis encoder."); + guac_client_data->audio = audio_stream_alloc(client, ogg_encoder); + break; + } + + } + + /* If an encoding is available, load the sound plugin */ + if (guac_client_data->audio != NULL) { + + /* Load sound plugin */ + if (freerdp_channels_load_plugin(channels, instance->settings, + "guac_rdpsnd", guac_client_data->audio)) + guac_client_log_error(client, + "Failed to load guac_rdpsnd plugin."); + + } + else + guac_client_log_info(client, + "No available audio encoding. Sound disabled."); /* Init color conversion structure */ clrconv = xnew(CLRCONV); @@ -425,6 +455,7 @@ int guac_client_init(guac_client* client, int argc, char** argv) { guac_client_data->mouse_button_mask = 0; guac_client_data->current_surface = GUAC_DEFAULT_LAYER; guac_client_data->clipboard = NULL; + guac_client_data->audio = NULL; /* Clear keysym state mapping and keymap */ memset(guac_client_data->keysym_state, 0,