Add remoting plugin for output streaming

Remoting plugin support streaming image of virtual output on drm-backend
to remote output. By appending remote-output section in weston.ini,
weston loads remoting plugin module and creates virtual outputs via
remoting plugin. The mode, host, and port properties are configurable in
remote-output section.

This plugin send motion jpeg images to client via RTP using gstreamer.
Client can receive by using following pipeline of gst-launch.

gst-launch-1.0 rtpbin name=rtpbin \
   udpsrc caps="application/x-rtp,media=(string)video,clock-rate=(int)90000,
		encoding-name=JPEG,payload=26" port=[PORTNUMBER] !
          rtpbin.recv_rtp_sink_0 \
   rtpbin. ! rtpjpegdepay ! jpegdec ! autovideosink \
   udpsrc port=[PORTNUMBER+1] ! rtpbin.recv_rtcp_sink_0 \
   rtpbin.send_rtcp_src_0 !
          udpsink port=[PORTNUMBER+2] sync=false async=false

where, PORTNUMBER is specified in weston.ini.

Signed-off-by: Tomohito Esaki <etom@igel.co.jp>
This commit is contained in:
Tomohito Esaki
2018-01-24 17:08:02 +09:00
parent f59dc1112b
commit f709d22038
9 changed files with 1271 additions and 0 deletions
+152
View File
@@ -61,6 +61,7 @@
#include "compositor-wayland.h"
#include "windowed-output-api.h"
#include "weston-debug.h"
#include "../remoting/remoting-plugin.h"
#define WINDOW_TITLE "Weston Compositor"
@@ -1973,6 +1974,154 @@ drm_heads_changed(struct wl_listener *listener, void *arg)
wet->init_failed = true;
}
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;
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;
}
wet_output_set_scale(output, section, 1, 0);
wet_output_set_transform(output, section, WL_OUTPUT_TRANSFORM_NORMAL,
UINT32_MAX);
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, "host", &host, NULL);
if (!host) {
weston_log("Cannot configure an output \"%s\". Invalid host\n",
output->name);
return -1;
}
api->set_host(output, host);
free(host);
weston_config_section_get_int(section, "port", &port, 0);
if (port <= 0 || 65533 < port) {
weston_log("Cannot configure an output \"%s\". Invalid port\n",
output->name);
return -1;
}
api->set_port(output, port);
return 0;
}
static void
remoted_output_init(struct weston_compositor *c,
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(c, 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 void
load_remoting(struct weston_compositor *c, struct weston_config *wc)
{
const struct weston_remoting_api *api = NULL;
int (*module_init)(struct weston_compositor *ec);
struct weston_config_section *section = NULL;
const char *section_name;
/* read remote-output section in weston.ini */
while (weston_config_next_section(wc, &section, &section_name)) {
if (strcmp(section_name, "remote-output"))
continue;
if (!api) {
char *module_name;
struct weston_config_section *core_section =
weston_config_get_section(wc, "core", NULL,
NULL);
weston_config_section_get_string(core_section,
"remoting",
&module_name,
"remoting-plugin.so");
module_init = weston_load_module(module_name,
"weston_module_init");
free(module_name);
if (!module_init) {
weston_log("Can't load remoting-plugin\n");
return;
}
if (module_init(c) < 0) {
weston_log("Remoting-plugin init failed\n");
return;
}
api = weston_remoting_get_api(c);
if (!api)
return;
}
remoted_output_init(c, section, api);
}
}
static int
load_drm_backend(struct weston_compositor *c,
int *argc, char **argv, struct weston_config *wc)
@@ -2015,6 +2164,9 @@ load_drm_backend(struct weston_compositor *c,
ret = weston_compositor_load_backend(c, WESTON_BACKEND_DRM,
&config.base);
/* remoting */
load_remoting(c, wc);
free(config.gbm_format);
free(config.seat_id);