char *gbm_format = NULL;
char *seat = NULL;
char *host = NULL;
+ char *pipeline = NULL;
int port, ret;
ret = api->set_mode(output, modeline);
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;
+ weston_config_section_get_string(section, "gst-pipeline", &pipeline,
+ NULL);
+ if (pipeline) {
+ api->set_gst_pipeline(output, pipeline);
+ 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);
- if (port <= 0 || 65533 < port) {
- weston_log("Cannot configure an output \"%s\". Invalid port\n",
- output->name);
- return -1;
+ 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;
char *host;
int port;
+ char *gst_pipeline;
const struct remoted_output_support_gbm_format *format;
struct weston_head *head;
static int
remoting_gst_pipeline_init(struct remoted_output *output)
{
- char pipeline_str[1024];
GstCaps *caps;
GError *err = NULL;
GstStateChangeReturn ret;
struct weston_mode *mode = output->output->current_mode;
- /* TODO: use encodebin instead of jpegenc */
- snprintf(pipeline_str, sizeof(pipeline_str),
- "rtpbin name=rtpbin "
- "appsrc name=src ! videoconvert ! video/x-raw,format=I420 ! "
- "jpegenc ! rtpjpegpay ! rtpbin.send_rtp_sink_0 "
- "rtpbin.send_rtp_src_0 ! udpsink name=sink host=%s port=%d "
- "rtpbin.send_rtcp_src_0 ! "
- "udpsink host=%s port=%d sync=false async=false "
- "udpsrc port=%d ! rtpbin.recv_rtcp_sink_0",
- output->host, output->port, output->host, output->port + 1,
- output->port + 2);
- weston_log("GST pipeline: %s\n", pipeline_str);
-
- output->pipeline = gst_parse_launch(pipeline_str, &err);
+ if (!output->gst_pipeline) {
+ char pipeline_str[1024];
+ /* TODO: use encodebin instead of jpegenc */
+ snprintf(pipeline_str, sizeof(pipeline_str),
+ "rtpbin name=rtpbin "
+ "appsrc name=src ! videoconvert ! "
+ "video/x-raw,format=I420 ! jpegenc ! rtpjpegpay ! "
+ "rtpbin.send_rtp_sink_0 "
+ "rtpbin.send_rtp_src_0 ! "
+ "udpsink name=sink host=%s port=%d "
+ "rtpbin.send_rtcp_src_0 ! "
+ "udpsink host=%s port=%d sync=false async=false "
+ "udpsrc port=%d ! rtpbin.recv_rtcp_sink_0",
+ 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) {
weston_log("Could not create gstreamer pipeline. Error: %s\n",
err->message);
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",
"format", G_TYPE_STRING,
output->format->gst_format_string,
if (remoted_output->host)
free(remoted_output->host);
+ if (remoted_output->gst_pipeline)
+ free(remoted_output->gst_pipeline);
wl_list_remove(&remoted_output->link);
weston_head_release(remoted_output->head);
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 = {
remoting_output_create,
remoting_output_is_remoted,
remoting_output_set_seat,
remoting_output_set_host,
remoting_output_set_port,
+ remoting_output_set_gst_pipeline,
};
WL_EXPORT int