From b3c4f205c94e55d574483160f5d38b0bfc7c1d16 Mon Sep 17 00:00:00 2001 From: Marius Vlad Date: Tue, 2 Jun 2020 12:47:13 +0300 Subject: main: Add the ability to load the remote plugin Streaming to 'remote' outputs needs the remote-plugin library. We build it automatically if we determine that the gst dependencies are satisfied, otherwise we're using a stub version for it. Unfortunatelly, upstream doesn't provide necessary header for the remoting.h so we copy-paste directly. Will follow up with upstream to provide headers for the plugins. Bug-AGl: SPEC-3280 Signed-off-by: Marius Vlad Change-Id: Ide277b402c511ed075fa1c5aaaf7770b50359c35 --- meson.build | 21 +++++++++ src/main.c | 151 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/remote.h | 78 ++++++++++++++++++++++++++++++ 3 files changed, 250 insertions(+) create mode 100644 src/remote.h diff --git a/meson.build b/meson.build index 9040f48..bc65c1c 100644 --- a/meson.build +++ b/meson.build @@ -46,6 +46,22 @@ prog_scanner = find_program(dep_scanner.get_pkgconfig_variable('wayland_scanner' dep_wp = dependency('wayland-protocols', version: '>= 1.18') dir_wp_base = dep_wp.get_pkgconfig_variable('pkgdatadir') +depnames = [ + 'gstreamer-1.0', 'gstreamer-allocators-1.0', + 'gstreamer-app-1.0', 'gstreamer-video-1.0', + 'gobject-2.0', 'glib-2.0' +] + +deps_remoting = [] +foreach depname : depnames + dep = dependency(depname, required: false) + if not dep.found() + message('Remoting requires @0@ which was not found. '.format(depname)) + endif +deps_remoting += dep +endforeach + + agl_shell_xml = files('protocol/agl-shell.xml') agl_shell_desktop_xml = files('protocol/agl-shell-desktop.xml') xdg_shell_xml = join_paths(dir_wp_base, 'stable', 'xdg-shell', 'xdg-shell.xml') @@ -159,6 +175,11 @@ if dep_libsystemd.found() message('Found systemd, enabling notify support') endif +if deps_remoting.length() == depnames.length() + config_h.set('HAVE_REMOTING', 1) + message('Found remoting depends, enabling remoting') +endif + configure_file(output: 'config.h', configuration: config_h) exe_agl_compositor = executable( diff --git a/src/main.c b/src/main.c index 2bbb800..4294c64 100644 --- a/src/main.c +++ b/src/main.c @@ -53,6 +53,10 @@ #include "agl-shell-server-protocol.h" +#ifdef HAVE_REMOTING +#include "remote.h" +#endif + static int cached_tm_mday = -1; static struct weston_log_scope *log_scope; @@ -548,6 +552,151 @@ heads_changed(struct wl_listener *listener, void *arg) } } +#ifdef HAVE_REMOTING +static int +drm_backend_remoted_output_configure(struct weston_output *output, + struct weston_config_section *section, + char *modeline, + const struct weston_remoting_api *api) +{ + char *gbm_format = NULL; + char *seat = NULL; + char *host = NULL; + char *pipeline = NULL; + int port, ret; + + ret = api->set_mode(output, modeline); + if (ret < 0) { + weston_log("Cannot configure an output \"%s\" using " + "weston_remoting_api. Invalid mode\n", + output->name); + return -1; + } + + /* FIXME: retrieve the scale and the transform from config file */ + weston_output_set_scale(output, 1); + weston_output_set_transform(output, WL_OUTPUT_TRANSFORM_NORMAL); + + weston_config_section_get_string(section, "gbm-format", + &gbm_format, NULL); + api->set_gbm_format(output, gbm_format); + free(gbm_format); + + weston_config_section_get_string(section, "seat", &seat, ""); + + api->set_seat(output, seat); + free(seat); + + weston_config_section_get_string(section, "gst-pipeline", &pipeline, + NULL); + if (pipeline) { + api->set_gst_pipeline(output, pipeline); + free(pipeline); + return 0; + } + + weston_config_section_get_string(section, "host", &host, NULL); + weston_config_section_get_int(section, "port", &port, 0); + if (!host || port <= 0 || 65533 < port) { + weston_log("Cannot configure an output \"%s\". " + "Need to specify gst-pipeline or " + "host and port (1-65533).\n", output->name); + } + api->set_host(output, host); + free(host); + api->set_port(output, port); + + return 0; +} + + +static void +remote_output_init(struct weston_compositor *compositor, + struct weston_config_section *section, + const struct weston_remoting_api *api) +{ + struct weston_output *output = NULL; + char *output_name, *modeline = NULL; + int ret; + + weston_config_section_get_string(section, "name", &output_name, NULL); + if (!output_name) + return; + + weston_config_section_get_string(section, "mode", &modeline, "off"); + if (strcmp(modeline, "off") == 0) + goto err; + + output = api->create_output(compositor, output_name); + if (!output) { + weston_log("Cannot create remoted output \"%s\".\n", + output_name); + goto err; + } + + ret = drm_backend_remoted_output_configure(output, section, + modeline, api); + if (ret < 0) { + weston_log("Cannot configure remoted output \"%s\".\n", + output_name); + goto err; + } + + if (weston_output_enable(output) < 0) { + weston_log("Enabling remoted output \"%s\" failed.\n", + output_name); + goto err; + } + + free(modeline); + free(output_name); + weston_log("remoted output '%s' enabled\n", output->name); + return; + +err: + free(modeline); + free(output_name); + if (output) + weston_output_destroy(output); + +} + +static int +load_remoting(struct weston_compositor *compositor, struct weston_config *config) +{ + const struct weston_remoting_api *api = NULL; + int (*module_init)(struct weston_compositor *wc); + struct weston_config_section *remote_section = NULL; + const char *section_name; + + module_init = weston_load_module("remoting-plugin.so", + "weston_module_init"); + if (!module_init) + return -1; + + if (module_init(compositor) < 0) + return -1; + + api = weston_remoting_get_api(compositor); + if (!api) + return -1; + + while (weston_config_next_section(config, &remote_section, §ion_name)) { + if (strcmp(section_name, "remote-output")) + continue; + remote_output_init(compositor, remote_section, api); + } + + return 0; +} +#else +static int +load_remoting(struct weston_compositor *compositor, struct weston_config *config) +{ + return -1; +} +#endif + static int load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) { @@ -595,6 +744,8 @@ load_drm_backend(struct ivi_compositor *ivi, int *argc, char *argv[]) goto error; } + load_remoting(ivi->compositor, ivi->config); + error: free(config.gbm_format); free(config.seat_id); diff --git a/src/remote.h b/src/remote.h new file mode 100644 index 0000000..fdd429c --- /dev/null +++ b/src/remote.h @@ -0,0 +1,78 @@ +/* + * Copyright © 2018 Renesas Electronics Corp. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial + * portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS + * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN + * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Authors: IGEL Co., Ltd. + */ + +#ifndef REMOTING_PLUGIN_H +#define REMOTING_PLUGIN_H + +#include +#include + +#define WESTON_REMOTING_API_NAME "weston_remoting_api_v1" + +struct weston_remoting_api { + /** Create remoted outputs + * + * Returns 0 on success, -1 on failure. + */ + struct weston_output *(*create_output)(struct weston_compositor *c, + char *name); + + /** Check if output is remoted */ + bool (*is_remoted_output)(struct weston_output *output); + + /** Set mode */ + int (*set_mode)(struct weston_output *output, const char *modeline); + + /** Set gbm format */ + void (*set_gbm_format)(struct weston_output *output, + const char *gbm_format); + + /** Set seat */ + void (*set_seat)(struct weston_output *output, const char *seat); + + /** Set the destination Host(IP Address) */ + void (*set_host)(struct weston_output *output, char *ip); + + /** Set the port number */ + void (*set_port)(struct weston_output *output, int port); + + /** Set the pipeline for gstreamer */ + void (*set_gst_pipeline)(struct weston_output *output, + char *gst_pipeline); +}; + +static inline const struct weston_remoting_api * +weston_remoting_get_api(struct weston_compositor *compositor) +{ + const void *api; + api = weston_plugin_api_get(compositor, WESTON_REMOTING_API_NAME, + sizeof(struct weston_remoting_api)); + + return (const struct weston_remoting_api *)api; +} + +#endif /* REMOTING_PLUGIN_H */ -- cgit 1.2.3-korg