diff --git a/src/protocols/vnc/client.c b/src/protocols/vnc/client.c index 7567d881..55065bb8 100644 --- a/src/protocols/vnc/client.c +++ b/src/protocols/vnc/client.c @@ -37,6 +37,7 @@ #include #include +#include #include @@ -44,9 +45,16 @@ #include #include +#include +#include +#ifdef ENABLE_OGG +#include +#endif + #include "client.h" #include "vnc_handlers.h" #include "guac_handlers.h" +#include "pa_handlers.h" /* Client plugin arguments */ const char* GUAC_CLIENT_ARGS[] = { @@ -61,6 +69,7 @@ const char* GUAC_CLIENT_ARGS[] = { "dest-host", "dest-port", #endif + "disable-audio", NULL }; @@ -88,8 +97,13 @@ int guac_client_init(guac_client* client, int argc, char** argv) { rfbClient* rfb_client; vnc_guac_client_data* guac_client_data; + + audio_args* args; + + pthread_t pa_read_thread, pa_send_thread; int read_only; + int i; /* Set up libvncclient logging */ rfbClientLog = guac_vnc_client_log_info; @@ -143,6 +157,67 @@ int guac_client_init(guac_client* client, int argc, char** argv) { /* Depth */ guac_vnc_set_pixel_format(rfb_client, atoi(argv[6])); + guac_client_data->audio_enabled = (strcmp(argv[7], "true") != 0); + + /* If audio enabled, choose an encoder */ + if (guac_client_data->audio_enabled) { + + /* Choose an encoding */ + for (i=0; client->info.audio_mimetypes[i] != NULL; i++) { + + const char* mimetype = client->info.audio_mimetypes[i]; + +#ifdef ENABLE_OGG + /* If Ogg is supported, done. */ + if (strcmp(mimetype, ogg_encoder->mimetype) == 0) { + guac_client_log_info(client, "Loading Ogg Vorbis encoder."); + guac_client_data->audio = audio_stream_alloc(client, + ogg_encoder); + break; + } +#endif + + /* If wav is supported, done. */ + if (strcmp(mimetype, wav_encoder->mimetype) == 0) { + guac_client_log_info(client, "Loading wav encoder."); + guac_client_data->audio = audio_stream_alloc(client, + wav_encoder); + break; + } + } + + /* If an encoding is available, load the sound plugin */ + if (guac_client_data->audio != NULL) { + + guac_client_data->audio_buffer = guac_pa_buffer_alloc(); + + args = malloc(sizeof(audio_args)); + args->audio = guac_client_data->audio; + args->audio_buffer = guac_client_data->audio_buffer; + + /* Create a thread to read audio data */ + if (pthread_create(&pa_read_thread, NULL, guac_pa_read_audio, (void*) args)) { + guac_protocol_send_error(client->socket, "Error initializing PulseAudio thread"); + guac_socket_flush(client->socket); + return 1; + } + + guac_client_data->audio_read_thread = &pa_read_thread; + + /* Create a thread to send audio data */ + if (pthread_create(&pa_send_thread, NULL, guac_pa_send_audio, (void*) args)) { + guac_protocol_send_error(client->socket, "Error initializing PulseAudio thread"); + guac_socket_flush(client->socket); + return 1; + } + + guac_client_data->audio_send_thread = &pa_send_thread; + } + else + guac_client_log_info(client, "No available audio encoding. Sound disabled."); + + } /* end if audio enabled */ + /* Hook into allocation so we can handle resize. */ guac_client_data->rfb_MallocFrameBuffer = rfb_client->MallocFrameBuffer; rfb_client->MallocFrameBuffer = guac_vnc_malloc_framebuffer; diff --git a/src/protocols/vnc/client.h b/src/protocols/vnc/client.h index 62c60ee2..dc84dc1d 100644 --- a/src/protocols/vnc/client.h +++ b/src/protocols/vnc/client.h @@ -38,8 +38,12 @@ #ifndef __GUAC_VNC_CLIENT_H #define __GUAC_VNC_CLIENT_H +#include +#include #include +#include "buffer.h" + extern char* __GUAC_CLIENT; typedef struct vnc_guac_client_data { @@ -53,8 +57,32 @@ typedef struct vnc_guac_client_data { int swap_red_blue; guac_layer* cursor; + + /** + * Whether audio is enabled. + */ + int audio_enabled; + + /** + * Audio output, if any. + */ + audio_stream* audio; + + /** + * Audio buffer, if any. + */ + buffer* audio_buffer; + + /** + * Handle to the audio read thread. + */ + pthread_t* audio_read_thread; + + /** + * Handle to the audio send thread. + */ + pthread_t* audio_send_thread; } vnc_guac_client_data; #endif -