From c8db957a0b3f762e89782990af7259c38c030a5b Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Tue, 17 May 2022 16:16:24 -0500 Subject: [PATCH] rdp: Add audio support Allow the front end to register audio setup and teardown functions. These functions should use FreeRDP's rdpsnd_server_context or audin_server_context and set up their own handler threads. The backend remains mostly ignorant to any audio details beyond setting up and tearing down. Signed-off-by: Derek Foreman --- include/libweston/backend-rdp.h | 9 ++++++++ libweston/backend-rdp/rdp.c | 39 +++++++++++++++++++++++++++++++-- libweston/backend-rdp/rdp.h | 8 +++++++ 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/include/libweston/backend-rdp.h b/include/libweston/backend-rdp.h index e88cd856..c9eb1609 100644 --- a/include/libweston/backend-rdp.h +++ b/include/libweston/backend-rdp.h @@ -57,6 +57,11 @@ weston_rdp_output_get_api(struct weston_compositor *compositor) #define WESTON_RDP_BACKEND_CONFIG_VERSION 2 +typedef void *(*rdp_audio_in_setup)(struct weston_compositor *c, void *vcm); +typedef void (*rdp_audio_in_teardown)(void *audio_private); +typedef void *(*rdp_audio_out_setup)(struct weston_compositor *c, void *vcm); +typedef void (*rdp_audio_out_teardown)(void *audio_private); + struct weston_rdp_backend_config { struct weston_backend_config base; char *bind_address; @@ -70,6 +75,10 @@ struct weston_rdp_backend_config { bool remotefx_codec; int external_listener_fd; int refresh_rate; + rdp_audio_in_setup audio_in_setup; + rdp_audio_in_teardown audio_in_teardown; + rdp_audio_out_setup audio_out_setup; + rdp_audio_out_teardown audio_out_teardown; }; #ifdef __cplusplus diff --git a/libweston/backend-rdp/rdp.c b/libweston/backend-rdp/rdp.c index 24e98c98..e78b26fa 100644 --- a/libweston/backend-rdp/rdp.c +++ b/libweston/backend-rdp/rdp.c @@ -668,10 +668,14 @@ out_error_stream: static void rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context) { + struct rdp_backend *b; unsigned i; + if (!context) return; + b = context->rdpBackend; + wl_list_remove(&context->item.link); for (i = 0; i < ARRAY_LENGTH(context->events); i++) { @@ -679,6 +683,12 @@ rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context) wl_event_source_remove(context->events[i]); } + if (context->audio_in_private) + b->audio_in_teardown(context->audio_in_private); + + if (context->audio_out_private) + b->audio_out_teardown(context->audio_out_private); + rdp_clipboard_destroy(context); if (context->vcm) @@ -936,11 +946,22 @@ xf_peer_activate(freerdp_peer* client) settings->CompressionEnabled = FALSE; } - if (settings->RedirectClipboard) { + settings->AudioPlayback = b->audio_out_setup && b->audio_out_teardown; + settings->AudioCapture = b->audio_in_setup && b->audio_in_teardown; + + if (settings->RedirectClipboard || + settings->AudioPlayback || + settings->AudioCapture) { if (!peerCtx->vcm) { - weston_log("Virtual channel is required for clipboard\n"); + weston_log("Virtual channel is required for clipboard, audio playback/capture\n"); goto error_exit; } + /* Audio setup will return NULL on failure, and we'll proceed without audio */ + if (settings->AudioPlayback) + peerCtx->audio_out_private = b->audio_out_setup(b->compositor, peerCtx->vcm); + + if (settings->AudioCapture) + peerCtx->audio_in_private = b->audio_in_setup(b->compositor, peerCtx->vcm); } if (output->base.width != (int)settings->DesktopWidth || @@ -1043,6 +1064,12 @@ error_exit: rdp_clipboard_destroy(peerCtx); + if (settings->AudioPlayback && peerCtx->audio_out_private) + b->audio_out_teardown(peerCtx->audio_out_private); + + if (settings->AudioCapture && peerCtx->audio_in_private) + b->audio_in_teardown(peerCtx->audio_in_private); + return FALSE; } @@ -1585,6 +1612,10 @@ rdp_backend_create(struct weston_compositor *compositor, b->no_clients_resize = config->no_clients_resize; b->force_no_compression = config->force_no_compression; b->remotefx_codec = config->remotefx_codec; + b->audio_in_setup = config->audio_in_setup; + b->audio_in_teardown = config->audio_in_teardown; + b->audio_out_setup = config->audio_out_setup; + b->audio_out_teardown = config->audio_out_teardown; b->debug = weston_compositor_add_log_scope(compositor, "rdp-backend", @@ -1729,6 +1760,10 @@ config_init_to_defaults(struct weston_rdp_backend_config *config) config->remotefx_codec = true; config->external_listener_fd = -1; config->refresh_rate = RDP_DEFAULT_FREQ; + config->audio_in_setup = NULL; + config->audio_in_teardown = NULL; + config->audio_out_setup = NULL; + config->audio_out_teardown = NULL; } WL_EXPORT int diff --git a/libweston/backend-rdp/rdp.h b/libweston/backend-rdp/rdp.h index 7fb42118..abc03a13 100644 --- a/libweston/backend-rdp/rdp.h +++ b/libweston/backend-rdp/rdp.h @@ -92,6 +92,11 @@ struct rdp_backend { int external_listener_fd; int rdp_monitor_refresh_rate; pid_t compositor_tid; + + rdp_audio_in_setup audio_in_setup; + rdp_audio_in_teardown audio_in_teardown; + rdp_audio_out_setup audio_out_setup; + rdp_audio_out_teardown audio_out_teardown; }; enum peer_item_flags { @@ -149,6 +154,9 @@ struct rdp_peer_context { /* Clipboard support */ CliprdrServerContext *clipboard_server_context; + void *audio_in_private; + void *audio_out_private; + struct rdp_clipboard_data_source *clipboard_client_data_source; struct rdp_clipboard_data_source *clipboard_inflight_client_data_source;