main: Add the ability to load the remote plugin 63/24663/4
authorMarius Vlad <marius.vlad@collabora.com>
Tue, 2 Jun 2020 09:47:13 +0000 (12:47 +0300)
committerJan-Simon Moeller <jsmoeller@linuxfoundation.org>
Mon, 15 Jun 2020 10:09:17 +0000 (10:09 +0000)
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 <marius.vlad@collabora.com>
Change-Id: Ide277b402c511ed075fa1c5aaaf7770b50359c35

meson.build
src/main.c
src/remote.h [new file with mode: 0644]

index 9040f48..bc65c1c 100644 (file)
@@ -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(
index 2bbb800..4294c64 100644 (file)
 
 #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, &section_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 (file)
index 0000000..fdd429c
--- /dev/null
@@ -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 <libweston/libweston.h>
+#include <libweston/plugin-registry.h>
+
+#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 */