summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-10-07 23:45:22 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-10-07 23:45:22 +0200
commitc4421ad81e941cd8a5375d50a2a3027733452f05 (patch)
tree848db958a463ab26f808d5c29936a33c60e3ea40 /src
parentcleanup for multiple binaries (diff)
added basic sydra-launch
Diffstat (limited to 'src')
-rw-r--r--src/Makefile19
-rw-r--r--src/options-launch.c214
-rw-r--r--src/options-launch.h60
-rw-r--r--src/pipelines-launch.c56
-rw-r--r--src/pipelines-launch.h44
-rw-r--r--src/sydra-launch.c325
6 files changed, 716 insertions, 2 deletions
diff --git a/src/Makefile b/src/Makefile
index 0553f08..a6ea007 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -37,7 +37,8 @@ include include.mk
endif
EXECUTABLE_RTP := sydra-rtp
-EXECUTABLES := $(EXECUTABLE_RTP)
+EXECUTABLE_LAUNCH := sydra-launch
+EXECUTABLES := $(EXECUTABLE_RTP) $(EXECUTABLE_LAUNCH)
C_OBJS_COMMON := log.o \
utils.o
@@ -48,8 +49,14 @@ C_OBJS_RTP := $(C_OBJS_COMMON) \
udp.o \
sydra-rtp.o
+C_OBJS_LAUNCH := $(C_OBJS_COMMON) \
+ options-launch.o \
+ pipelines-launch.o \
+ sydra-launch.o
+
C_SRCS_RTP := $(C_OBJS_RTP:%.o=%.c)
-C_SRCS := $(C_SRCS_RTP)
+C_SRCS_LAUNCH := $(C_OBJS_LAUNCH:%.o=%.c)
+C_SRCS := $(C_SRCS_RTP) $(C_SRCS_LAUNCH)
.PHONY: clean cleanall distclean manpage install install-bin uninstall remove
@@ -68,11 +75,15 @@ endif
$(EXECUTABLE_RTP): $(C_OBJS_RTP)
$(CC) $(C_OBJS_RTP) -o $@ $(LDFLAGS)
+$(EXECUTABLE_LAUNCH): $(C_OBJS_LAUNCH)
+ $(CC) $(C_OBJS_LAUNCH) -o $@ $(LDFLAGS)
+
%.o: %.c
$(CC) $(CFLAGS) -c $<
strip: $(EXECUTABLES)
$(STRIP) -s $(EXECUTABLE_RTP)
+ $(STRIP) -s $(EXECUTABLE_LAUNCH)
distclean: clean
@@ -100,10 +111,12 @@ install: all $(INSTALL_TARGETS)
install-bin: $(EXECUTABLES)
$(INSTALL) -d $(DESTDIR)$(BINDIR)
$(INSTALL) -m 755 $(EXECUTABLE_RTP) $(DESTDIR)$(BINDIR)
+ $(INSTALL) -m 755 $(EXECUTABLE_LAUNCH) $(DESTDIR)$(BINDIR)
install-man: manpage
$(INSTALL) -d $(DESTDIR)$(MANDIR)/man8/
$(INSTALL) -m 644 ../doc/$(EXECUTABLE_RTP).8 $(DESTDIR)$(MANDIR)/man8/$(EXECUTABLE_RTP).8
+ $(INSTALL) -m 644 ../doc/$(EXECUTABLE_LAUNCH).8 $(DESTDIR)$(MANDIR)/man8/$(EXECUTABLE_LAUNCH).8
uninstall: remove
@@ -111,6 +124,8 @@ remove: $(REMOVE_TARGETS)
remove-bin:
rm -f $(DESTDIR)$(BINDIR)/$(EXECUTABLE_RTP)
+ rm -f $(DESTDIR)$(BINDIR)/$(EXECUTABLE_LAUNCH)
remove-man:
rm -f $(DESTDIR)$(MANDIR)/man8/$(EXECUTABLE_RTP).8
+ rm -f $(DESTDIR)$(MANDIR)/man8/$(EXECUTABLE_LAUNCH).8
diff --git a/src/options-launch.c b/src/options-launch.c
new file mode 100644
index 0000000..fad40fe
--- /dev/null
+++ b/src/options-launch.c
@@ -0,0 +1,214 @@
+/*
+ * sydra
+ *
+ * sydra is a toolbox which allows you to set up multiple bidirectional
+ * Video/Audio streams from external locations.
+ * sydra has been written to be used for the Elevate Festival in Graz
+ * Austria in order to involve external locations to present themselves
+ * at the festival.
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of sydra.
+ *
+ * sydra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * sydra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with sydra. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders hereby
+ * grant permission for non-GPL-compatible GStreamer plugins to be used
+ * and distributed together with GStreamer and sydra.
+ * This permission goes above and beyond the permissions granted by the
+ * GPL license sydra is covered by.
+ */
+
+#include "datatypes.h"
+#include "config-launch.h"
+
+#include "options-launch.h"
+#include "log.h"
+
+#include <stdio.h>
+#include <string.h>
+#include <glib.h>
+#include <gst/gst.h>
+
+static void options_defaults(options_t* opt)
+{
+ if(!opt)
+ return;
+
+ opt->progname_ = g_strdup("sydra-rtp");
+ opt->daemonize_ = TRUE;
+ opt->username_ = NULL;
+ opt->groupname_ = NULL;
+ opt->chroot_dir_ = NULL;
+ opt->pid_file_ = NULL;
+ opt->log_targets_ = NULL;
+ opt->debug_ = FALSE;
+
+ opt->appname_ = NULL;
+ opt->pipeline_ = NULL;
+}
+
+static int options_parse_post(options_t* opt);
+
+int options_parse(options_t* opt, int argc, char* argv[])
+{
+ if(!opt)
+ return -1;
+
+ options_defaults(opt);
+
+ g_free(opt->progname_);
+ opt->progname_ = g_strdup(argv[0]);
+ if(!opt->progname_)
+ return -127;
+
+ gboolean show_version = FALSE;
+ GOptionEntry main_entries[] = {
+ { "version", 'v', 0, G_OPTION_ARG_NONE, &show_version,
+ "print version info and exit", NULL },
+ { "nodaemonize", 'D', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt->daemonize_,
+ "don't run in background", NULL },
+ { "username", 'u', 0, G_OPTION_ARG_STRING, &opt->username_,
+ "change to this user", "USERNAME" },
+ { "group", 'g', 0, G_OPTION_ARG_STRING, &opt->groupname_,
+ "change to this group", "GROUP" },
+ { "chroot", 'C', 0, G_OPTION_ARG_STRING, &opt->chroot_dir_,
+ "chroot to this directory", "PATH" },
+ { "write-pid", 'P', 0, G_OPTION_ARG_STRING, &opt->pid_file_,
+ "write pid to this file", "PATH" },
+ { "log", 'L', 0, G_OPTION_ARG_STRING_ARRAY, &opt->log_targets_,
+ "add a log target, can be invoked several times", "<TARGET>:<LEVEL>[,<PARAM1>[,<PARAM2>..]]" },
+ { "debug", 'U', 0, G_OPTION_ARG_NONE, &opt->debug_,
+ "don't daemonize and log to stdout with maximum log level", NULL },
+ { "appname", 'n', 0, G_OPTION_ARG_STRING, &opt->appname_,
+ "set the application name (will be used by xvimagesink for window title)", "NAME" },
+ { "pipeline", 'p', 0, G_OPTION_ARG_STRING, &opt->pipeline_,
+ "the gst-launch style pipeline description", "PIPELINE DESCRIPTION" },
+ { NULL }
+ };
+ GOptionContext *ctx = g_option_context_new("- spreadspace streaming hydra ");
+ GOptionGroup* main_group = g_option_group_new ("main", "Application Options",
+ "Show Application Options", opt, NULL);
+ if(main_group)
+ g_option_group_add_entries(main_group, main_entries);
+
+ GOptionGroup* gst_group = gst_init_get_option_group();
+ if(!main_group || !gst_group) {
+ printf("ERROR: Failed to initialize: memory error\n");
+ return -127;
+ }
+ g_option_context_set_main_group(ctx, main_group);
+ g_option_context_add_group(ctx, gst_group);
+
+ GError *err = NULL;
+ if(!g_option_context_parse(ctx, &argc, &argv, &err)) {
+ printf("ERROR: Failed to initialize: %s\n", err->message);
+ g_error_free(err);
+ return 1;
+ }
+
+ if(show_version)
+ return -1;
+
+ return options_parse_post(opt);
+}
+
+static int options_parse_post(options_t* opt)
+{
+ if(!opt->pipeline_) {
+ printf("ERROR: the pipeline description can not be omitted!\n");
+ return -2;
+ }
+
+ if(opt->debug_) {
+ opt->daemonize_ = 0;
+ g_strfreev(opt->log_targets_);
+ opt->log_targets_ = g_new(gchar*, 2);
+ if(!opt->log_targets_) return -127;
+ opt->log_targets_[0] = g_strdup("stdout:5");
+ if(!(opt->log_targets_[0])) return -127;
+ opt->log_targets_[1] = NULL;
+ }
+
+ if(!opt->log_targets_ || !g_strv_length(opt->log_targets_)) {
+ opt->log_targets_ = g_new(gchar*, 2);
+ if(!opt->log_targets_) return -127;
+ opt->log_targets_[0] = g_strdup("syslog:3,sydra-launch,daemon");
+ if(!(opt->log_targets_[0])) return -127;
+ opt->log_targets_[1] = NULL;
+ }
+
+ return 0;
+}
+
+void options_clear(options_t* opt)
+{
+ if(!opt)
+ return;
+
+ g_free(opt->progname_);
+ g_free(opt->username_);
+ g_free(opt->groupname_);
+ g_free(opt->chroot_dir_);
+ g_free(opt->pid_file_);
+ g_strfreev(opt->log_targets_);
+ g_free(opt->appname_);
+ g_free(opt->pipeline_);
+}
+
+void options_print_version()
+{
+ printf("%s\n", VERSION_STRING_0);
+#if defined(__clang__)
+ printf("%s, using CLANG %s\n", VERSION_STRING_1, __clang_version__);
+#elif defined(__GNUC__)
+ printf("%s, using GCC %d.%d.%d\n", VERSION_STRING_1, __GNUC__, __GNUC_MINOR__, __GNUC_PATCHLEVEL__);
+#else
+ printf("%s\n", VERSION_STRING_1);
+#endif
+ const gchar *nano_str;
+ guint major, minor, micro, nano;
+ gst_version(&major, &minor, &micro, &nano);
+ if (nano == 1)
+ nano_str = " (CVS)";
+ else if (nano == 2)
+ nano_str = " (Prerelease)";
+ else
+ nano_str = "";
+ printf(" linked against GStreamer %d.%d.%d%s\n", major, minor, micro, nano_str);
+}
+
+void options_print(options_t* opt)
+{
+ if(!opt)
+ return;
+
+ printf(" progname: '%s'\n", opt->progname_);
+ printf(" daemonize: %s\n", opt->daemonize_ ? "true" : "false");
+ printf(" username: '%s'\n", opt->username_);
+ printf(" groupname: '%s'\n", opt->groupname_);
+ printf(" chroot_dir: '%s'\n", opt->chroot_dir_);
+ printf(" pid_file: '%s'\n", opt->pid_file_);
+ printf(" log_targets: \n");
+ gchar* lt = opt->log_targets_ ? g_strjoinv ("'\n '", opt->log_targets_) : NULL;
+ if(lt) {
+ printf(" '%s'\n", lt);
+ g_free(lt);
+ }
+ printf(" debug: %s\n", opt->debug_ ? "true" : "false");
+ printf(" appname: >>%s<<\n", opt->appname_);
+ printf(" pipeline: >>%s<<\n", opt->pipeline_);
+}
diff --git a/src/options-launch.h b/src/options-launch.h
new file mode 100644
index 0000000..f939458
--- /dev/null
+++ b/src/options-launch.h
@@ -0,0 +1,60 @@
+/*
+ * sydra
+ *
+ * sydra is a toolbox which allows you to set up multiple bidirectional
+ * Video/Audio streams from external locations.
+ * sydra has been written to be used for the Elevate Festival in Graz
+ * Austria in order to involve external locations to present themselves
+ * at the festival.
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of sydra.
+ *
+ * sydra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * sydra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with sydra. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders hereby
+ * grant permission for non-GPL-compatible GStreamer plugins to be used
+ * and distributed together with GStreamer and sydra.
+ * This permission goes above and beyond the permissions granted by the
+ * GPL license sydra is covered by.
+ */
+
+#ifndef SYDRA_options_h_INCLUDED
+#define SYDRA_options_h_INCLUDED
+
+#include "datatypes.h"
+
+struct options_struct {
+ gchar* progname_;
+ gboolean daemonize_;
+ gchar* username_;
+ gchar* groupname_;
+ gchar* chroot_dir_;
+ gchar* pid_file_;
+ gchar** log_targets_;
+ gboolean debug_;
+
+ gchar* appname_;
+ gchar* pipeline_;
+};
+typedef struct options_struct options_t;
+
+int options_parse(options_t* opt, int argc, char* argv[]);
+void options_clear(options_t* opt);
+void options_print_version();
+void options_print(options_t* opt);
+
+#endif
diff --git a/src/pipelines-launch.c b/src/pipelines-launch.c
new file mode 100644
index 0000000..56050b3
--- /dev/null
+++ b/src/pipelines-launch.c
@@ -0,0 +1,56 @@
+/*
+ * sydra
+ *
+ * sydra is a toolbox which allows you to set up multiple bidirectional
+ * Video/Audio streams from external locations.
+ * sydra has been written to be used for the Elevate Festival in Graz
+ * Austria in order to involve external locations to present themselves
+ * at the festival.
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of sydra.
+ *
+ * sydra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * sydra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with sydra. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders hereby
+ * grant permission for non-GPL-compatible GStreamer plugins to be used
+ * and distributed together with GStreamer and sydra.
+ * This permission goes above and beyond the permissions granted by the
+ * GPL license sydra is covered by.
+ */
+
+#include "datatypes.h"
+
+#include <gst/gst.h>
+#include <stdio.h>
+#include <string.h>
+
+#include "pipelines-launch.h"
+#include "options-launch.h"
+#include "utils.h"
+#include "log.h"
+
+GstElement* create_pipeline(options_t* opt)
+{
+ GstElement *pipeline = gst_pipeline_new ("sydra-launch-receiver");
+ if(!pipeline) {
+ log_printf(ERROR, "Creating pipeline failed!");
+ return NULL;
+ }
+
+ log_printf(INFO, "pipeline created successfully!");
+ return pipeline;
+}
diff --git a/src/pipelines-launch.h b/src/pipelines-launch.h
new file mode 100644
index 0000000..965deb1
--- /dev/null
+++ b/src/pipelines-launch.h
@@ -0,0 +1,44 @@
+/*
+ * sydra
+ *
+ * sydra is a toolbox which allows you to set up multiple bidirectional
+ * Video/Audio streams from external locations.
+ * sydra has been written to be used for the Elevate Festival in Graz
+ * Austria in order to involve external locations to present themselves
+ * at the festival.
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of sydra.
+ *
+ * sydra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * sydra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with sydra. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders hereby
+ * grant permission for non-GPL-compatible GStreamer plugins to be used
+ * and distributed together with GStreamer and sydra.
+ * This permission goes above and beyond the permissions granted by the
+ * GPL license sydra is covered by.
+ */
+
+#ifndef SYDRA_pipelines_h_INCLUDED
+#define SYDRA_pipelines_h_INCLUDED
+
+#include "datatypes.h"
+#include <gst/gst.h>
+#include "options-launch.h"
+
+GstElement* create_pipeline(options_t* opt);
+
+#endif
diff --git a/src/sydra-launch.c b/src/sydra-launch.c
new file mode 100644
index 0000000..8417695
--- /dev/null
+++ b/src/sydra-launch.c
@@ -0,0 +1,325 @@
+/*
+ * sydra
+ *
+ * sydra is a toolbox which allows you to set up multiple bidirectional
+ * Video/Audio streams from external locations.
+ * sydra has been written to be used for the Elevate Festival in Graz
+ * Austria in order to involve external locations to present themselves
+ * at the festival.
+ *
+ *
+ * Copyright (C) 2014 Christian Pointner <equinox@spreadspace.org>
+ *
+ * This file is part of sydra.
+ *
+ * sydra is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * any later version.
+ *
+ * sydra is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with sydra. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * In addition, as a special exception, the copyright holders hereby
+ * grant permission for non-GPL-compatible GStreamer plugins to be used
+ * and distributed together with GStreamer and sydra.
+ * This permission goes above and beyond the permissions granted by the
+ * GPL license sydra is covered by.
+ */
+
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/socket.h>
+
+#include <glib.h>
+#include <glib-unix.h>
+#include <gst/gst.h>
+
+#include "datatypes.h"
+#include "options-launch.h"
+#include "log.h"
+#include "daemon.h"
+#include "utils.h"
+#include "pipelines-launch.h"
+
+
+static gboolean sig_handler_terminate(gpointer user_data)
+{
+ GMainLoop *loop = (GMainLoop *)user_data;
+
+ log_printf(NOTICE, "signal received, closing application");
+ g_main_loop_quit(loop);
+ return TRUE;
+}
+
+static gboolean bus_call(GstBus *bus, GstMessage *msg, gpointer data)
+{
+ GMainLoop *loop = (GMainLoop *)data;
+
+ switch (GST_MESSAGE_TYPE(msg)) {
+ case GST_MESSAGE_EOS: {
+ log_printf(NOTICE, "End of stream");
+ g_main_loop_quit(loop);
+ break;
+ }
+ case GST_MESSAGE_APPLICATION: {
+ log_printf(DEBUG, "Got Application Message!");
+ const GstStructure* ms = gst_message_get_structure(msg);
+ gboolean quit;
+ gst_structure_get_boolean(ms, "quit", &quit);
+ if(quit) {
+ const gchar* reason = gst_structure_get_string (ms, "reason");
+ log_printf(NOTICE, "closing due to message: %s", reason);
+ g_main_loop_quit(loop);
+ }
+ break;
+ }
+ case GST_MESSAGE_INFO: {
+ GError *info;
+ gst_message_parse_info(msg, &info, NULL);
+ log_printf(INFO, "%s", info->message);
+ g_error_free(info);
+ break;
+ }
+ case GST_MESSAGE_WARNING: {
+ GError *warning;
+ gst_message_parse_warning(msg, &warning, NULL);
+ log_printf(WARNING, "%s", warning->message);
+ g_error_free(warning);
+ break;
+ }
+ case GST_MESSAGE_ERROR: {
+ GError *error;
+ gst_message_parse_error(msg, &error, NULL);
+ log_printf(ERROR, "%s", error->message);
+ g_error_free(error);
+ g_main_loop_quit(loop);
+ break;
+ }
+ case GST_MESSAGE_STATE_CHANGED: {
+ GstState old_state, new_state;
+ gst_message_parse_state_changed(msg, &old_state, &new_state, NULL);
+ log_printf(DEBUG, "Element '%s' changed state from %s to %s",
+ (msg->src ? GST_OBJECT_NAME(msg->src) : "NULL"),
+ gst_element_state_get_name(old_state),
+ gst_element_state_get_name(new_state));
+ break;
+ }
+ case GST_MESSAGE_NEW_CLOCK:
+ {
+ GstClock *clock;
+ gst_message_parse_new_clock(msg, &clock);
+ log_printf(NOTICE, "New clock: %s", (clock ? GST_OBJECT_NAME (clock) : "NULL"));
+ break;
+ }
+ case GST_MESSAGE_QOS: {
+ guint64 running_time, stream_time, timestamp, duration;
+ gst_message_parse_qos(msg, NULL, &running_time, &stream_time, &timestamp, &duration);
+ log_printf(WARNING, "Element '%s' dropped frames running_time=%lu, stream_time=%lu, timestamp=%lu, duration=%lu",
+ (msg->src ? GST_OBJECT_NAME(msg->src) : "NULL"), running_time, stream_time, timestamp, duration);
+ break;
+ }
+ /* case GST_MESSAGE_STREAM_STATUS: */
+ /* { */
+ /* GstStreamStatusType type; */
+ /* GstElement *owner; */
+ /* const GValue *val; */
+ /* gchar *path, *ownerstr; */
+ /* GstTask *task = NULL; */
+
+ /* gst_message_parse_stream_status (msg, &type, &owner); */
+ /* val = gst_message_get_stream_status_object (msg); */
+
+ /* path = gst_object_get_path_string (GST_MESSAGE_SRC (msg)); */
+ /* ownerstr = gst_object_get_path_string (GST_OBJECT (owner)); */
+ /* log_printf(DEBUG,"Recevied Stream-Status message type: %d, source: %s, owner: %s, object: type %s, value %p", */
+ /* type, path, ownerstr, G_VALUE_TYPE_NAME (val), g_value_get_object (val)); */
+ /* g_free (path); */
+ /* g_free (ownerstr); */
+
+ /* /\* see if we know how to deal with this object *\/ */
+ /* if (G_VALUE_TYPE (val) == GST_TYPE_TASK) { */
+ /* task = g_value_get_object (val); */
+ /* } */
+
+ /* switch (type) { */
+ /* case GST_STREAM_STATUS_TYPE_CREATE: */
+ /* log_printf(DEBUG," created task %p", task); */
+ /* break; */
+ /* case GST_STREAM_STATUS_TYPE_ENTER: */
+ /* /\* log_printf(DEBUG," raising task priority"); *\/ */
+ /* /\* setpriority (PRIO_PROCESS, 0, -10); *\/ */
+ /* break; */
+ /* case GST_STREAM_STATUS_TYPE_LEAVE: */
+ /* break; */
+ /* default: */
+ /* break; */
+ /* } */
+ /* break; */
+ /* } */
+ default:
+ /* log_printf(DEBUG, "unkonwn message %s from %s", GST_MESSAGE_TYPE_NAME(msg), GST_MESSAGE_SRC_NAME(msg)); */
+ return TRUE;
+ }
+ return TRUE;
+}
+
+int main_loop(options_t* opt)
+{
+ log_printf(NOTICE, "entering main loop");
+
+ GstElement *pipeline = create_pipeline(opt);
+ if(!pipeline) {
+ log_printf(ERROR, "creating pipeline failed - exitting");
+ return -1;
+ }
+
+ GMainLoop *loop = g_main_loop_new(NULL, FALSE);
+
+ GstBus *bus = gst_pipeline_get_bus(GST_PIPELINE(pipeline));
+ gst_bus_add_watch(bus, bus_call, loop);
+ gst_object_unref(GST_OBJECT(bus));
+
+ gulong deep_notify_id = 0;
+ if(opt->debug_) {
+ deep_notify_id = g_signal_connect(pipeline, "deep-notify",
+ G_CALLBACK(gst_object_default_deep_notify), NULL);
+ }
+
+ log_printf(NOTICE, "Set State: Paused");
+ gst_element_set_state(pipeline, GST_STATE_PAUSED);
+ log_printf(NOTICE, "Set State: Playing");
+ gst_element_set_state(pipeline, GST_STATE_PLAYING);
+
+ g_unix_signal_add(SIGHUP, sig_handler_terminate, loop);
+ g_unix_signal_add(SIGINT, sig_handler_terminate, loop);
+ g_unix_signal_add(SIGTERM, sig_handler_terminate, loop);
+ g_main_loop_run(loop);
+
+ if (deep_notify_id != 0)
+ g_signal_handler_disconnect(pipeline, deep_notify_id);
+
+ log_printf(NOTICE, "Stopping pipeline");
+ gst_element_set_state(pipeline, GST_STATE_NULL);
+ gst_object_unref(GST_OBJECT(pipeline));
+
+ return 0;
+}
+
+int main(int argc, char* argv[])
+{
+ log_init();
+ log_close();
+
+ options_t opt;
+ int ret = options_parse(&opt, argc, argv);
+ if(ret) {
+ if(ret == -1) {
+ options_print_version();
+ ret = 0;
+ }
+ options_clear(&opt);
+ log_close();
+ exit(ret);
+ }
+
+ guint len = g_strv_length(opt.log_targets_);
+ guint i;
+ for(i = 0; i < len; ++i) {
+ ret = log_add_target(opt.log_targets_[i]);
+ if(ret) {
+ switch(ret) {
+ case -2: fprintf(stderr, "memory error on log_add_target, exitting\n"); break;
+ case -3: fprintf(stderr, "unknown log target: '%s', exitting\n", (char*)(opt.log_targets_[i])); break;
+ case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", (char*)(opt.log_targets_[i])); break;
+ default: fprintf(stderr, "syntax error near: '%s', exitting\n", (char*)(opt.log_targets_[i])); break;
+ }
+
+ options_clear(&opt);
+ log_close();
+ exit(ret);
+ }
+ }
+
+ log_printf(NOTICE, "just started...");
+
+ if(opt.debug_)
+ options_print(&opt);
+
+ if(opt.appname_)
+ g_set_prgname (opt.appname_);
+ else
+ g_set_prgname (opt.progname_);
+
+ priv_info_t priv;
+ if(opt.username_)
+ if(priv_init(&priv, opt.username_, opt.groupname_)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+
+ FILE* pid_file = NULL;
+ if(opt.pid_file_) {
+ pid_file = fopen(opt.pid_file_, "w");
+ if(!pid_file) {
+ log_printf(WARNING, "unable to open pid file: %s", strerror(errno));
+ }
+ }
+
+ if(opt.chroot_dir_)
+ if(do_chroot(opt.chroot_dir_)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+ if(opt.username_)
+ if(priv_drop(&priv)) {
+ options_clear(&opt);
+ log_close();
+ exit(-1);
+ }
+
+ if(opt.daemonize_) {
+ pid_t oldpid = getpid();
+ daemonize();
+ log_printf(INFO, "running in background now (old pid: %d)", oldpid);
+ }
+
+ if(pid_file) {
+ pid_t pid = getpid();
+ fprintf(pid_file, "%d", pid);
+ fclose(pid_file);
+ }
+
+ const gchar *nano_str;
+ guint major, minor, micro, nano;
+ gst_version(&major, &minor, &micro, &nano);
+ if (nano == 1)
+ nano_str = " (CVS)";
+ else if (nano == 2)
+ nano_str = " (Prerelease)";
+ else
+ nano_str = "";
+ log_printf(NOTICE, "sydra-launch linked against GStreamer %d.%d.%d%s", major, minor, micro, nano_str);
+
+ ret = main_loop(&opt);
+
+ options_clear(&opt);
+
+ log_printf(NOTICE, "sydra-launch shutdown");
+
+ gst_deinit();
+ log_close();
+
+ return ret;
+}