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 <derek.foreman@collabora.com>
This commit is contained in:
@@ -57,6 +57,11 @@ weston_rdp_output_get_api(struct weston_compositor *compositor)
|
|||||||
|
|
||||||
#define WESTON_RDP_BACKEND_CONFIG_VERSION 2
|
#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_rdp_backend_config {
|
||||||
struct weston_backend_config base;
|
struct weston_backend_config base;
|
||||||
char *bind_address;
|
char *bind_address;
|
||||||
@@ -70,6 +75,10 @@ struct weston_rdp_backend_config {
|
|||||||
bool remotefx_codec;
|
bool remotefx_codec;
|
||||||
int external_listener_fd;
|
int external_listener_fd;
|
||||||
int refresh_rate;
|
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
|
#ifdef __cplusplus
|
||||||
|
|||||||
@@ -668,10 +668,14 @@ out_error_stream:
|
|||||||
static void
|
static void
|
||||||
rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)
|
rdp_peer_context_free(freerdp_peer* client, RdpPeerContext* context)
|
||||||
{
|
{
|
||||||
|
struct rdp_backend *b;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
b = context->rdpBackend;
|
||||||
|
|
||||||
wl_list_remove(&context->item.link);
|
wl_list_remove(&context->item.link);
|
||||||
|
|
||||||
for (i = 0; i < ARRAY_LENGTH(context->events); i++) {
|
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]);
|
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);
|
rdp_clipboard_destroy(context);
|
||||||
|
|
||||||
if (context->vcm)
|
if (context->vcm)
|
||||||
@@ -936,11 +946,22 @@ xf_peer_activate(freerdp_peer* client)
|
|||||||
settings->CompressionEnabled = FALSE;
|
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) {
|
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;
|
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 ||
|
if (output->base.width != (int)settings->DesktopWidth ||
|
||||||
@@ -1043,6 +1064,12 @@ error_exit:
|
|||||||
|
|
||||||
rdp_clipboard_destroy(peerCtx);
|
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;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1585,6 +1612,10 @@ rdp_backend_create(struct weston_compositor *compositor,
|
|||||||
b->no_clients_resize = config->no_clients_resize;
|
b->no_clients_resize = config->no_clients_resize;
|
||||||
b->force_no_compression = config->force_no_compression;
|
b->force_no_compression = config->force_no_compression;
|
||||||
b->remotefx_codec = config->remotefx_codec;
|
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,
|
b->debug = weston_compositor_add_log_scope(compositor,
|
||||||
"rdp-backend",
|
"rdp-backend",
|
||||||
@@ -1729,6 +1760,10 @@ config_init_to_defaults(struct weston_rdp_backend_config *config)
|
|||||||
config->remotefx_codec = true;
|
config->remotefx_codec = true;
|
||||||
config->external_listener_fd = -1;
|
config->external_listener_fd = -1;
|
||||||
config->refresh_rate = RDP_DEFAULT_FREQ;
|
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
|
WL_EXPORT int
|
||||||
|
|||||||
@@ -92,6 +92,11 @@ struct rdp_backend {
|
|||||||
int external_listener_fd;
|
int external_listener_fd;
|
||||||
int rdp_monitor_refresh_rate;
|
int rdp_monitor_refresh_rate;
|
||||||
pid_t compositor_tid;
|
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 {
|
enum peer_item_flags {
|
||||||
@@ -149,6 +154,9 @@ struct rdp_peer_context {
|
|||||||
/* Clipboard support */
|
/* Clipboard support */
|
||||||
CliprdrServerContext *clipboard_server_context;
|
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_client_data_source;
|
||||||
struct rdp_clipboard_data_source *clipboard_inflight_client_data_source;
|
struct rdp_clipboard_data_source *clipboard_inflight_client_data_source;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user