remoting: make a gstreamer pipeline configurable

Allow a gstreamer pipeline to be configurable via an weston.ini. It is
necessary that source is appsrc, its name is "src", and sink name is
"sink" in pipeline. Also, remoting plugin ignore port and host
configuration if the gst-pipeline is specified.
dev
Tomohito Esaki 6 years ago committed by Daniel Stone
parent 974390a5fa
commit 3ea03bb85e
  1. 25
      compositor/main.c
  2. 6
      man/weston-drm.man
  3. 59
      remoting/remoting-plugin.c
  4. 4
      remoting/remoting-plugin.h

@ -2196,6 +2196,7 @@ drm_backend_remoted_output_configure(struct weston_output *output,
char *gbm_format = NULL; char *gbm_format = NULL;
char *seat = NULL; char *seat = NULL;
char *host = NULL; char *host = NULL;
char *pipeline = NULL;
int port, ret; int port, ret;
ret = api->set_mode(output, modeline); ret = api->set_mode(output, modeline);
@ -2220,21 +2221,23 @@ drm_backend_remoted_output_configure(struct weston_output *output,
api->set_seat(output, seat); api->set_seat(output, seat);
free(seat); free(seat);
weston_config_section_get_string(section, "host", &host, NULL); weston_config_section_get_string(section, "gst-pipeline", &pipeline,
if (!host) { NULL);
weston_log("Cannot configure an output \"%s\". Invalid host\n", if (pipeline) {
output->name); api->set_gst_pipeline(output, pipeline);
return -1; free(pipeline);
return 0;
} }
api->set_host(output, host);
free(host);
weston_config_section_get_string(section, "host", &host, NULL);
weston_config_section_get_int(section, "port", &port, 0); weston_config_section_get_int(section, "port", &port, 0);
if (port <= 0 || 65533 < port) { if (!host || port <= 0 || 65533 < port) {
weston_log("Cannot configure an output \"%s\". Invalid port\n", weston_log("Cannot configure an output \"%s\". "
output->name); "Need to specify gst-pipeline or "
return -1; "host and port (1-65533).\n", output->name);
} }
api->set_host(output, host);
free(host);
api->set_port(output, port); api->set_port(output, port);
return 0; return 0;

@ -168,6 +168,12 @@ transmitted to.
\fBport\fR=\fIport\fR \fBport\fR=\fIport\fR
Specify the port number to transmit the remote output to. Usable port range Specify the port number to transmit the remote output to. Usable port range
is 1-65533. is 1-65533.
.TP
\fBgst-pipeline\fR=\fIpipeline\fR
Specify the gstreamer pipeline. It is necessary that source is appsrc,
its name is "src", and sink name is "sink" in
.I pipeline\fR.
Ignore port and host configuration if the gst-pipeline is specified.
. .
.\" *************************************************************** .\" ***************************************************************

@ -97,6 +97,7 @@ struct remoted_output {
char *host; char *host;
int port; int port;
char *gst_pipeline;
const struct remoted_output_support_gbm_format *format; const struct remoted_output_support_gbm_format *format;
struct weston_head *head; struct weston_head *head;
@ -180,26 +181,31 @@ remoting_gst_bus_sync_handler(GstBus *bus, GstMessage *message,
static int static int
remoting_gst_pipeline_init(struct remoted_output *output) remoting_gst_pipeline_init(struct remoted_output *output)
{ {
char pipeline_str[1024];
GstCaps *caps; GstCaps *caps;
GError *err = NULL; GError *err = NULL;
GstStateChangeReturn ret; GstStateChangeReturn ret;
struct weston_mode *mode = output->output->current_mode; struct weston_mode *mode = output->output->current_mode;
/* TODO: use encodebin instead of jpegenc */ if (!output->gst_pipeline) {
snprintf(pipeline_str, sizeof(pipeline_str), char pipeline_str[1024];
"rtpbin name=rtpbin " /* TODO: use encodebin instead of jpegenc */
"appsrc name=src ! videoconvert ! video/x-raw,format=I420 ! " snprintf(pipeline_str, sizeof(pipeline_str),
"jpegenc ! rtpjpegpay ! rtpbin.send_rtp_sink_0 " "rtpbin name=rtpbin "
"rtpbin.send_rtp_src_0 ! udpsink name=sink host=%s port=%d " "appsrc name=src ! videoconvert ! "
"rtpbin.send_rtcp_src_0 ! " "video/x-raw,format=I420 ! jpegenc ! rtpjpegpay ! "
"udpsink host=%s port=%d sync=false async=false " "rtpbin.send_rtp_sink_0 "
"udpsrc port=%d ! rtpbin.recv_rtcp_sink_0", "rtpbin.send_rtp_src_0 ! "
output->host, output->port, output->host, output->port + 1, "udpsink name=sink host=%s port=%d "
output->port + 2); "rtpbin.send_rtcp_src_0 ! "
weston_log("GST pipeline: %s\n", pipeline_str); "udpsink host=%s port=%d sync=false async=false "
"udpsrc port=%d ! rtpbin.recv_rtcp_sink_0",
output->pipeline = gst_parse_launch(pipeline_str, &err); output->host, output->port, output->host,
output->port + 1, output->port + 2);
output->gst_pipeline = strdup(pipeline_str);
}
weston_log("GST pipeline: %s\n", output->gst_pipeline);
output->pipeline = gst_parse_launch(output->gst_pipeline, &err);
if (!output->pipeline) { if (!output->pipeline) {
weston_log("Could not create gstreamer pipeline. Error: %s\n", weston_log("Could not create gstreamer pipeline. Error: %s\n",
err->message); err->message);
@ -214,6 +220,12 @@ remoting_gst_pipeline_init(struct remoted_output *output)
goto err; goto err;
} }
/* check sink */
if (!gst_bin_get_by_name(GST_BIN(output->pipeline), "sink")) {
weston_log("Could not get sink from gstreamer pipeline\n");
goto err;
}
caps = gst_caps_new_simple("video/x-raw", caps = gst_caps_new_simple("video/x-raw",
"format", G_TYPE_STRING, "format", G_TYPE_STRING,
output->format->gst_format_string, output->format->gst_format_string,
@ -626,6 +638,8 @@ remoting_output_destroy(struct weston_output *output)
if (remoted_output->host) if (remoted_output->host)
free(remoted_output->host); free(remoted_output->host);
if (remoted_output->gst_pipeline)
free(remoted_output->gst_pipeline);
wl_list_remove(&remoted_output->link); wl_list_remove(&remoted_output->link);
weston_head_release(remoted_output->head); weston_head_release(remoted_output->head);
@ -853,6 +867,20 @@ remoting_output_set_port(struct weston_output *output, int port)
remoted_output->port = port; remoted_output->port = port;
} }
static void
remoting_output_set_gst_pipeline(struct weston_output *output,
char *gst_pipeline)
{
struct remoted_output *remoted_output = lookup_remoted_output(output);
if (!remoted_output)
return;
if (remoted_output->gst_pipeline)
free(remoted_output->gst_pipeline);
remoted_output->gst_pipeline = strdup(gst_pipeline);
}
static const struct weston_remoting_api remoting_api = { static const struct weston_remoting_api remoting_api = {
remoting_output_create, remoting_output_create,
remoting_output_is_remoted, remoting_output_is_remoted,
@ -861,6 +889,7 @@ static const struct weston_remoting_api remoting_api = {
remoting_output_set_seat, remoting_output_set_seat,
remoting_output_set_host, remoting_output_set_host,
remoting_output_set_port, remoting_output_set_port,
remoting_output_set_gst_pipeline,
}; };
WL_EXPORT int WL_EXPORT int

@ -59,6 +59,10 @@ struct weston_remoting_api {
/** Set the port number */ /** Set the port number */
void (*set_port)(struct weston_output *output, int port); 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 * static inline const struct weston_remoting_api *

Loading…
Cancel
Save