summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-09-26 00:29:10 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-09-26 00:29:10 +0200
commita32b141e1c7bbdc5e36e9d3debf262eb1c26ddfc (patch)
treeff8b802b606ccb88ebff1db1110a23595d66aa16
parentimproved default pipeline (diff)
now using GOptions for command line parsing
-rw-r--r--src/Makefile2
-rw-r--r--src/options.c462
-rw-r--r--src/options.h55
-rw-r--r--src/slist.c138
-rw-r--r--src/slist.h59
-rw-r--r--src/string_list.c77
-rw-r--r--src/string_list.h49
-rw-r--r--src/sydra.c40
8 files changed, 256 insertions, 626 deletions
diff --git a/src/Makefile b/src/Makefile
index eb9f39b..3fcf405 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -41,8 +41,6 @@ EXECUTABLE := sydra
C_OBJS := log.o \
options.o \
- slist.o \
- string_list.o \
utils.o \
pipelines.o \
udp.o \
diff --git a/src/options.c b/src/options.c
index 1d5a0d6..6f7a0fc 100644
--- a/src/options.c
+++ b/src/options.c
@@ -39,192 +39,32 @@
#include "options.h"
#include "log.h"
-#include <stdlib.h>
#include <stdio.h>
-#include <string.h>
-#include <ctype.h>
-
-#define PARSE_BOOL_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- VALUE = 1;
-
-#define PARSE_INVERSE_BOOL_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- VALUE = 0;
-
-#define PARSE_INT_PARAM(SHORT, LONG, VALUE, BASE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1) \
- return i; \
- VALUE = strtol(argv[i+1], (char **)NULL, BASE); \
- argc--; \
- i++; \
- }
-
-#define PARSE_STRING_PARAM(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- if(VALUE) free(VALUE); \
- VALUE = strdup(argv[i+1]); \
- if(!VALUE) \
- return -2; \
- argc--; \
- i++; \
- }
-
-#define PARSE_STRING_PARAM_SEC(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- if(VALUE) free(VALUE); \
- VALUE = strdup(argv[i+1]); \
- if(!VALUE) \
- return -2; \
- size_t j; \
- for(j=0; j < strlen(argv[i+1]); ++j) \
- argv[i+1][j] = '#'; \
- argc--; \
- i++; \
- }
-
-#define PARSE_STRING_LIST(SHORT, LONG, LIST) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- int ret = string_list_add(&LIST, argv[i+1]); \
- if(ret == -2) \
- return ret; \
- else if(ret) \
- return i+1; \
- argc--; \
- i++; \
- }
-
-#define PARSE_RESOLV_TYPE(SHORT, LONG, VALUE) \
- else if(!strcmp(str,SHORT) || !strcmp(str,LONG)) \
- { \
- if(argc < 1 || argv[i+1][0] == '-') \
- return i; \
- if(!strcmp(argv[i+1], "4") || \
- !strcmp(argv[i+1], "ipv4")) \
- VALUE = IPV4_ONLY; \
- else if(!strcmp(argv[i+1], "6") || \
- !strcmp(argv[i+1], "ipv6")) \
- VALUE = IPV6_ONLY; \
- else \
- return i+1; \
- argc--; \
- i++; \
- }
+#include <glib.h>
+#include <gst/gst.h>
-
-int options_parse(options_t* opt, int argc, char* argv[])
-{
- if(!opt)
- return -1;
-
- options_default(opt);
-
- if(opt->progname_)
- free(opt->progname_);
- opt->progname_ = strdup(argv[0]);
- if(!opt->progname_)
- return -2;
-
- argc--;
-
- int i;
- for(i=1; argc > 0; ++i)
- {
- char* str = argv[i];
- argc--;
-
- if(!strcmp(str,"-h") || !strcmp(str,"--help"))
- return -1;
- else if(!strcmp(str,"-v") || !strcmp(str,"--version"))
- return -3;
- PARSE_INVERSE_BOOL_PARAM("-D","--nodaemonize", opt->daemonize_)
- PARSE_STRING_PARAM("-u","--username", opt->username_)
- PARSE_STRING_PARAM("-g","--groupname", opt->groupname_)
- PARSE_STRING_PARAM("-C","--chroot", opt->chroot_dir_)
- PARSE_STRING_PARAM("-P","--write-pid", opt->pid_file_)
- PARSE_STRING_LIST("-L","--log", opt->log_targets_)
- PARSE_BOOL_PARAM("-U", "--debug", opt->debug_)
- PARSE_STRING_PARAM("-n","--appname", opt->appname_)
- PARSE_STRING_PARAM("-vs","--video-source", opt->video_src_)
- PARSE_STRING_PARAM("-ve","--video-encoder", opt->video_enc_)
- PARSE_STRING_PARAM("-vp","--video-payloader", opt->video_payloader_)
- PARSE_STRING_PARAM("-as","--audio-source", opt->audio_src_)
- PARSE_STRING_PARAM("-ae","--audio-encoder", opt->audio_enc_)
- PARSE_STRING_PARAM("-ap","--audio-payloader", opt->audio_payloader_)
- PARSE_STRING_PARAM("-a","--rtp-host", opt->rtp_host_)
- PARSE_INT_PARAM("-o","--rtp-port-base", opt->rtp_port_base_, 10)
- PARSE_STRING_PARAM("-A","--rtp-addr-local", opt->rtp_addr_local_)
- PARSE_INT_PARAM("-O","--rtp-port-base-local", opt->rtp_port_base_local_, 10)
- PARSE_INT_PARAM("-t","--timeout", opt->timeout_, 10)
- PARSE_STRING_PARAM("-V","--videosink", opt->preview_videosink_)
- PARSE_STRING_PARAM("-rv","--rec-video-encoder", opt->video_enc_rec_)
- PARSE_STRING_PARAM("-ra","--rec-audio-encoder", opt->audio_enc_rec_)
- PARSE_STRING_PARAM("-rm","--rec-mux", opt->rec_mux_)
- PARSE_STRING_PARAM("-R","--rec-name-format", opt->rec_name_format_)
- else
- return i;
- }
-
- if(opt->rtp_port_base_ < 1 || opt->rtp_port_base_ > 65535 ||
- opt->rtp_port_base_local_ < 1 || opt->rtp_port_base_local_ > 65535)
- return -4;
-
- if(opt->timeout_ < 0)
- return -5;
-
- if(opt->debug_) {
- string_list_add(&opt->log_targets_, "stdout:5");
- opt->daemonize_ = 0;
- }
-
- if(!opt->log_targets_.first_) {
- string_list_add(&opt->log_targets_, "syslog:3,sydra,daemon");
- }
-
- return 0;
-}
-
-void options_parse_post(options_t* opt)
-{
- if(!opt)
- return;
-
-// nothing yet
-}
-
-void options_default(options_t* opt)
+static void options_defaults(options_t* opt)
{
if(!opt)
return;
- opt->progname_ = strdup("sydra");
+ opt->progname_ = g_strdup("sydra");
opt->daemonize_ = 1;
opt->username_ = NULL;
opt->groupname_ = NULL;
opt->chroot_dir_ = NULL;
opt->pid_file_ = NULL;
- string_list_init(&opt->log_targets_);
+ opt->log_targets_ = NULL;
opt->debug_ = 0;
opt->appname_ = NULL;
- opt->video_src_ = strdup("v4l2src ! videoconvert ! videoscale ! video/x-raw,format=I420,width=864,height=480,framerate=25/1,pixel-aspect-ratio=1/1 ! identity");
- opt->video_enc_ = strdup("vp8enc keyframe-max-dist=25 error-resilient=2 end-usage=1 target-bitrate=1200000 cpu-used=4 deadline=1000000 threads=2");
- opt->video_payloader_ = strdup("rtpvp8pay");
+ opt->video_src_ = g_strdup("v4l2src ! videoconvert ! videoscale ! video/x-raw,format=I420,width=864,height=480,framerate=25/1,pixel-aspect-ratio=1/1 ! identity");
+ opt->video_enc_ = g_strdup("vp8enc keyframe-max-dist=25 error-resilient=2 end-usage=1 target-bitrate=1200000 cpu-used=4 deadline=1000000 threads=2");
+ opt->video_payloader_ = g_strdup("rtpvp8pay");
- opt->audio_src_ = strdup("autoaudiosrc ! audio/x-raw,format=S16LE,channels=1,rate=48000 ! identity");
- opt->audio_enc_ = strdup("opusenc bitrate=64000 cbr=true packet-loss-percentage=0 inband-fec=false");
- opt->audio_payloader_ = strdup("rtpopuspay");
+ opt->audio_src_ = g_strdup("autoaudiosrc ! audio/x-raw,format=S16LE,channels=1,rate=48000 ! identity");
+ opt->audio_enc_ = g_strdup("opusenc bitrate=64000 cbr=true packet-loss-percentage=0 inband-fec=false");
+ opt->audio_payloader_ = g_strdup("rtpopuspay");
opt->rtp_host_ = NULL;
opt->rtp_port_base_ = 5000;
@@ -237,91 +77,219 @@ void options_default(options_t* opt)
opt->video_enc_rec_ = NULL;
opt->audio_enc_rec_ = NULL;
opt->rec_mux_ = NULL;
- opt->rec_name_format_ = strdup("./recordings/%Y-%m-%d_%H-%M-%S");
+ opt->rec_name_format_ = g_strdup("./recordings/%Y-%m-%d_%H-%M-%S");
}
-void options_clear(options_t* opt)
+static GOptionGroup* options_get_av_group(options_t* opt)
+{
+ GOptionEntry av_entries[] = {
+ { "video-source", 0, 0, G_OPTION_ARG_STRING, &opt->video_src_,
+ "pipeline for raw video (i.e. videotestsrc)", "BIN DESCRIPTION" },
+ { "video-encoder", 0, 0, G_OPTION_ARG_STRING, &opt->video_enc_,
+ "pipeline for video encoder (i.e. videoconvert ! vp8enc)", "BIN DESCRIPTION" },
+ { "video-payloader", 0, 0, G_OPTION_ARG_STRING, &opt->video_payloader_,
+ "video RTP payloader element (i.e. rtpvp8pay)", "ELEMENT" },
+ { "audio-source", 0, 0, G_OPTION_ARG_STRING, &opt->audio_src_,
+ "pipeline for raw audio (i.e. audiotestsrc)", "BIN DESCRIPTION" },
+ { "audio-encoder", 0, 0, G_OPTION_ARG_STRING, &opt->audio_enc_,
+ "pipeline for audio encoder (i.e. audioconvert ! opusenc)", "BIN DESCRIPTION" },
+ { "audio-payloader", 0, 0, G_OPTION_ARG_STRING, &opt->audio_payloader_,
+ "audio RTP payloader element (i.e. rtpopuspay)", "ELEMENT" },
+ { NULL }
+ };
+ GOptionGroup* av_group = g_option_group_new ("av", "Audio/Video Options",
+ "Show Audio/Video Options", NULL, NULL);
+ if(!av_group) return NULL;
+ g_option_group_add_entries(av_group, av_entries);
+
+ return av_group;
+}
+
+static GOptionGroup* options_get_rtp_group(options_t* opt)
+{
+ GOptionEntry rtp_entries[] = {
+ { "rtp-host", 'a', 0, G_OPTION_ARG_STRING, &opt->rtp_host_,
+ "remote host for RTP packets", "HOST" },
+ { "rtp-port-base", 'o', 0, G_OPTION_ARG_INT, &opt->rtp_port_base_,
+ "base number for remote ports", "PORT" },
+ { "rtp-addr-local", 'A', 0, G_OPTION_ARG_STRING, &opt->rtp_addr_local_,
+ "local address to bind to", "ADDRESS" },
+ { "rtp-port-base-local", 'O', 0, G_OPTION_ARG_INT, &opt->rtp_port_base_local_,
+ "base number for local ports to bind to", "PORT" },
+ { "timeout", 't', 0, G_OPTION_ARG_INT, &opt->timeout_,
+ "client timeout in seconds (0 means no timeout)", "VALUE" },
+ { NULL }
+ };
+ GOptionGroup* rtp_group = g_option_group_new ("rtp", "RTP Options",
+ "Show RTP Options", NULL, NULL);
+ if(!rtp_group) return NULL;
+ g_option_group_add_entries(rtp_group, rtp_entries);
+
+ return rtp_group;
+}
+
+static GOptionGroup* options_get_rec_group(options_t* opt)
+{
+ GOptionEntry rec_entries[] = {
+ { "rec-video-encoder", 0, 0, G_OPTION_ARG_STRING, &opt->video_enc_rec_,
+ "pipeline for video encoder for recording (i.e. videoconvert ! jpegenc) - leave empty to use same as for RTP", "BIN DESCRIPTION" },
+ { "rec-audio-encoder", 0, 0, G_OPTION_ARG_STRING, &opt->audio_enc_rec_,
+ "pipeline for audio encoder for recording (i.e. audioconvert ! vorbisenc) - leave empty to use same as for RTP", "BIN DESCRIPTION" },
+ { "rec-mux", 0, 0, G_OPTION_ARG_STRING, &opt->rec_mux_,
+ "muxer elemenent for recording (i.e. matroskamux) - leave empty to disable recording", "ELEMENT" },
+ { "rec-name-format", 0, 0, G_OPTION_ARG_STRING, &opt->rec_name_format_,
+ "the recording file name format string, see manpage of strftime for the syntax", "FORMATSTRING" },
+ { NULL }
+ };
+ GOptionGroup* rec_group = g_option_group_new ("rec", "Recording Options",
+ "Show Recording Options", NULL, NULL);
+ if(!rec_group) return NULL;
+ g_option_group_add_entries(rec_group, rec_entries);
+
+ return rec_group;
+}
+
+static int options_parse_post(options_t* opt);
+
+int options_parse(options_t* opt, int argc, char* argv[])
{
if(!opt)
- return;
+ return -1;
+
+ options_defaults(opt);
+
+ g_free(opt->progname_);
+ opt->progname_ = g_strdup(argv[0]);
+ if(!opt->progname_)
+ return -255;
+
+ 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" },
+ { "videosink", 'V', 0, G_OPTION_ARG_STRING, &opt->preview_videosink_,
+ "video sink element for local preview (i.e. xvimagesink) - leave empty to disable preview", "BIN DESCRIPTION" },
+ { NULL }
+ };
+ GOptionContext *ctx = g_option_context_new("- spreadspace streaming hydra ");
+ g_option_context_add_main_entries(ctx, main_entries, NULL);
+
+ GOptionGroup* av_group = options_get_av_group(opt);
+ GOptionGroup* rtp_group = options_get_rtp_group(opt);
+ GOptionGroup* rec_group = options_get_rec_group(opt);
+ GOptionGroup* gst_group = gst_init_get_option_group();
+ if(!av_group || !rtp_group || !rec_group || !gst_group) {
+ printf("Failed to initialize: memory error\n");
+ return -255;
+ }
+ g_option_context_add_group(ctx, av_group);
+ g_option_context_add_group(ctx, rtp_group);
+ g_option_context_add_group(ctx, rec_group);
+ g_option_context_add_group(ctx, gst_group);
+ GError *err = NULL;
+ if(!g_option_context_parse(ctx, &argc, &argv, &err)) {
+ printf("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->rtp_port_base_ < 1 || opt->rtp_port_base_ > 65535 ||
+ opt->rtp_port_base_local_ < 1 || opt->rtp_port_base_local_ > 65535) {
+ printf("Failed to initialize: rtp port is invalid\n");
+ return -2;
+ }
+
+ if(opt->timeout_ < 0) {
+ printf("Failed to initialize: timeout is invalid\n");
+ return -3;
+ }
+
+ if(opt->debug_) {
+ opt->daemonize_ = 0;
+ g_strfreev(opt->log_targets_);
+ opt->log_targets_ = g_new(gchar*, 2);
+ if(!opt->log_targets_) return -255;
+ opt->log_targets_[0] = g_strdup("stdout:5");
+ if(!(opt->log_targets_[0])) return -255;
+ opt->log_targets_[1] = NULL;
+ }
+
+ if(!g_strv_length(opt->log_targets_)) {
+ opt->log_targets_ = g_new(gchar*, 2);
+ if(!opt->log_targets_) return -255;
+ opt->log_targets_[0] = g_strdup("syslog:3,sydra,daemon");
+ if(!(opt->log_targets_[0])) return -255;
+ opt->log_targets_[1] = NULL;
+ }
- if(opt->progname_)
- free(opt->progname_);
- if(opt->username_)
- free(opt->username_);
- if(opt->groupname_)
- free(opt->groupname_);
- if(opt->chroot_dir_)
- free(opt->chroot_dir_);
- if(opt->pid_file_)
- free(opt->pid_file_);
- string_list_clear(&opt->log_targets_);
- if(opt->appname_)
- free(opt->appname_);
- if(opt->video_src_)
- free(opt->video_src_);
- if(opt->video_enc_)
- free(opt->video_enc_);
- if(opt->video_payloader_)
- free(opt->video_payloader_);
- if(opt->audio_src_)
- free(opt->audio_src_);
- if(opt->audio_enc_)
- free(opt->audio_enc_);
- if(opt->audio_payloader_)
- free(opt->audio_payloader_);
- if(opt->rtp_host_)
- free(opt->rtp_host_);
- if(opt->rtp_addr_local_)
- free(opt->rtp_addr_local_);
- if(opt->preview_videosink_)
- free(opt->preview_videosink_);
- if(opt->video_enc_rec_)
- free(opt->video_enc_rec_);
- if(opt->audio_enc_rec_)
- free(opt->audio_enc_rec_);
- if(opt->rec_mux_)
- free(opt->rec_mux_);
- if(opt->rec_name_format_)
- free(opt->rec_name_format_);
+ return 0;
}
-void options_print_usage()
+void options_clear(options_t* opt)
{
- printf("USAGE:\n");
- printf("sydra [-h|--help] prints this...\n");
- printf(" [-v|--version] print version info and exit\n");
- printf(" [-D|--nodaemonize] don't run in background\n");
- printf(" [-u|--username] <username> change to this user\n");
- printf(" [-g|--groupname] <groupname> change to this group\n");
- printf(" [-C|--chroot] <path> chroot to this directory\n");
- printf(" [-P|--write-pid] <path> write pid to this file\n");
- printf(" [-L|--log] <target>:<level>[,<param1>[,<param2>..]]\n");
- printf(" add a log target, can be invoked several times\n");
- printf(" [-U|--debug] don't daemonize and log to stdout with maximum log level\n");
- printf(" [-n|--appname] <name> set the application name (will be used by xvimagesink for window title)\n");
- printf(" [-vs|--video-source pipeline for raw video (i.e. videotestsrc)\n");
- printf(" [-ve|--video-encoder pipeline for video encoder (stream)\n");
- printf(" [-vp|--video-payloader video payloader element (i.e. rtpvp8pay)\n");
- printf(" [-as|--audio-source pipeline for raw audio (audiotestsrc)\n");
- printf(" [-ae|--audio-encoder pipeline for audio encoder (stream)\n");
- printf(" [-ap|--audio-payloader audio payloader element (i.e. rptopuspay)\n");
- printf(" [-a|--rtp-host remote host for RTP packets\n");
- printf(" [-o|--rtp-port-base base number for remote ports\n");
- printf(" [-A|--rtp-addr-local local address to bind to\n");
- printf(" [-O|--rtp-port-base-local base number for local ports to bind to\n");
- printf(" [-t|--timeout client timeout (0 means no timeout)\n");
- printf(" [-V|--videosink video sink element for local preview (i.e. xvimagesink) - leave empty to disable preview\n");
- printf(" [-rv|--rec-video-encoder pipeline for video encoder (recording - leave empty for same as stream)\n");
- printf(" [-ra|--rec-audio-encoder pipeline for audio encoder (recording - leave empty for same as stream)\n");
- printf(" [-rm|--rec-mux muxer elemenent (i.e. matroskamux)\n");
- printf(" [-r|--rec-name-format] <format> the recording file name format, see manpage of strftime for the syntax\n");
+ 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->video_src_);
+ g_free(opt->video_enc_);
+ g_free(opt->video_payloader_);
+ g_free(opt->audio_src_);
+ g_free(opt->audio_enc_);
+ g_free(opt->audio_payloader_);
+ g_free(opt->rtp_host_);
+ g_free(opt->rtp_addr_local_);
+ g_free(opt->preview_videosink_);
+ g_free(opt->video_enc_rec_);
+ g_free(opt->audio_enc_rec_);
+ g_free(opt->rec_mux_);
+ g_free(opt->rec_name_format_);
}
void options_print_version()
{
printf("%s\n", VERSION_STRING_0);
printf("%s\n", VERSION_STRING_1);
+ 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)
@@ -330,14 +298,18 @@ void options_print(options_t* opt)
return;
printf(" progname: '%s'\n", opt->progname_);
- printf(" daemonize: %d\n", opt->daemonize_);
+ 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");
- string_list_print(&opt->log_targets_, " '", "'\n");
- printf(" debug: %s\n", !opt->debug_ ? "false" : "true");
+ 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(" video_src: >>%s<<\n", opt->video_src_);
printf(" video_enc: >>%s<<\n", opt->video_enc_);
diff --git a/src/options.h b/src/options.h
index 6009246..f639ad4 100644
--- a/src/options.h
+++ b/src/options.h
@@ -36,50 +36,45 @@
#ifndef SYDRA_options_h_INCLUDED
#define SYDRA_options_h_INCLUDED
-#include <sys/types.h>
-#include "string_list.h"
#include "datatypes.h"
struct options_struct {
- char* progname_;
- int daemonize_;
- char* username_;
- char* groupname_;
- char* chroot_dir_;
- char* pid_file_;
- string_list_t log_targets_;
- int debug_;
+ gchar* progname_;
+ gboolean daemonize_;
+ gchar* username_;
+ gchar* groupname_;
+ gchar* chroot_dir_;
+ gchar* pid_file_;
+ gchar** log_targets_;
+ gboolean debug_;
- char* appname_;
+ gchar* appname_;
- char* video_src_;
- char* video_enc_;
- char* video_payloader_;
+ gchar* video_src_;
+ gchar* video_enc_;
+ gchar* video_payloader_;
- char* audio_src_;
- char* audio_enc_;
- char* audio_payloader_;
+ gchar* audio_src_;
+ gchar* audio_enc_;
+ gchar* audio_payloader_;
- char* rtp_host_;
- int rtp_port_base_;
- char* rtp_addr_local_;
- int rtp_port_base_local_;
- int timeout_;
+ gchar* rtp_host_;
+ gint rtp_port_base_;
+ gchar* rtp_addr_local_;
+ gint rtp_port_base_local_;
+ gint timeout_;
- char* preview_videosink_;
+ gchar* preview_videosink_;
- char* video_enc_rec_;
- char* audio_enc_rec_;
- char* rec_mux_;
- char* rec_name_format_;
+ gchar* video_enc_rec_;
+ gchar* audio_enc_rec_;
+ gchar* rec_mux_;
+ gchar* rec_name_format_;
};
typedef struct options_struct options_t;
int options_parse(options_t* opt, int argc, char* argv[]);
-void options_parse_post(options_t* opt);
-void options_default(options_t* opt);
void options_clear(options_t* opt);
-void options_print_usage();
void options_print_version();
void options_print(options_t* opt);
diff --git a/src/slist.c b/src/slist.c
deleted file mode 100644
index 8138159..0000000
--- a/src/slist.c
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * 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.
- * Sydra is based on GStreamer and is written in C.
- *
- *
- * 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 <unistd.h>
-#include <stdlib.h>
-
-#include "datatypes.h"
-
-#include "slist.h"
-
-slist_element_t* slist_get_last(slist_element_t* first)
-{
- if(!first)
- return NULL;
-
- while(first->next_)
- first = first->next_;
-
- return first;
-}
-
-int slist_init(slist_t* lst, void (*delete_element)(void*))
-{
- if(!lst || !delete_element)
- return -1;
-
- lst->delete_element = delete_element;
- lst->first_ = NULL;
-
- return 0;
-}
-
-slist_element_t* slist_add(slist_t* lst, void* data)
-{
- if(!lst || !data)
- return NULL;
-
- slist_element_t* new_element = malloc(sizeof(slist_element_t));
- if(!new_element)
- return NULL;
-
- new_element->data_ = data;
- new_element->next_ = NULL;
-
- if(!lst->first_)
- lst->first_ = new_element;
- else
- slist_get_last(lst->first_)->next_ = new_element;
-
- return new_element;
-}
-
-void slist_remove(slist_t* lst, void* data)
-{
- if(!lst || !lst->first_ || !data)
- return;
-
- slist_element_t* tmp = lst->first_->next_;
- slist_element_t* prev = lst->first_;
- if(lst->first_->data_ == data) {
- lst->first_ = tmp;
- lst->delete_element(prev->data_);
- free(prev);
- }
- else {
- while(tmp) {
- if(tmp->data_ == data) {
- prev->next_ = tmp->next_;
- lst->delete_element(tmp->data_);
- free(tmp);
- return;
- }
- prev = tmp;
- tmp = tmp->next_;
- }
- }
-}
-
-void slist_clear(slist_t* lst)
-{
- if(!lst || !lst->first_)
- return;
-
- do {
- slist_element_t* deletee = lst->first_;
- lst->first_ = lst->first_->next_;
- lst->delete_element(deletee->data_);
- free(deletee);
- }
- while(lst->first_);
-
- lst->first_ = NULL;
-}
-
-int slist_length(slist_t* lst)
-{
- if(!lst || !lst->first_)
- return 0;
-
- int len = 0;
- slist_element_t* tmp;
- for(tmp = lst->first_; tmp; tmp = tmp->next_)
- len++;
-
- return len;
-}
diff --git a/src/slist.h b/src/slist.h
deleted file mode 100644
index 7a81638..0000000
--- a/src/slist.h
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * 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.
- * Sydra is based on GStreamer and is written in C.
- *
- *
- * 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_slist_h_INCLUDED
-#define SYDRA_slist_h_INCLUDED
-
-struct slist_element_struct {
- void* data_;
- struct slist_element_struct* next_;
-};
-typedef struct slist_element_struct slist_element_t;
-
-slist_element_t* slist_get_last(slist_element_t* first);
-
-struct slist_struct {
- void (*delete_element)(void* element);
- slist_element_t* first_;
-};
-typedef struct slist_struct slist_t;
-
-int slist_init(slist_t* lst, void (*delete_element)(void*));
-slist_element_t* slist_add(slist_t* lst, void* data);
-void slist_remove(slist_t* lst, void* data);
-void slist_clear(slist_t* lst);
-int slist_length(slist_t* lst);
-
-#endif
diff --git a/src/string_list.c b/src/string_list.c
deleted file mode 100644
index f666797..0000000
--- a/src/string_list.c
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * 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.
- * Sydra is based on GStreamer and is written in C.
- *
- *
- * 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 <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include "string_list.h"
-#include "slist.h"
-
-int string_list_init(string_list_t* list)
-{
- return slist_init(list, &free);
-}
-
-void string_list_clear(string_list_t* list)
-{
- slist_clear(list);
-}
-
-int string_list_add(string_list_t* list, const char* string)
-{
- if(!list)
- return -1;
-
- char* tmp = strdup(string);
- if(slist_add(list, tmp) == NULL) {
- free(tmp);
- return -2;
- }
-
- return 0;
-}
-
-void string_list_print(string_list_t* list, const char* head, const char* tail)
-{
- if(!list)
- return;
-
- slist_element_t* tmp = list->first_;
- while(tmp) {
- printf("%s%s%s", head, (char*)(tmp->data_), tail);
- tmp = tmp->next_;
- }
-}
diff --git a/src/string_list.h b/src/string_list.h
deleted file mode 100644
index fdd5316..0000000
--- a/src/string_list.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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.
- * Sydra is based on GStreamer and is written in C.
- *
- *
- * 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_string_list_h_INCLUDED
-#define SYDRA_string_list_h_INCLUDED
-
-#include "slist.h"
-
-typedef slist_t string_list_t;
-
-int string_list_init(string_list_t* list);
-void string_list_clear(string_list_t* list);
-int string_list_add(string_list_t* list, const char* string);
-
-void string_list_print(string_list_t* list, const char* head, const char* tail);
-
-#endif
diff --git a/src/sydra.c b/src/sydra.c
index 877172a..085eea2 100644
--- a/src/sydra.c
+++ b/src/sydra.c
@@ -47,7 +47,6 @@
#include "datatypes.h"
#include "options.h"
-#include "string_list.h"
#include "log.h"
#include "daemon.h"
#include "utils.h"
@@ -215,61 +214,51 @@ int main_loop(options_t* opt)
int main(int argc, char* argv[])
{
log_init();
+ log_close();
options_t opt;
int ret = options_parse(&opt, argc, argv);
if(ret) {
- if(ret > 0)
- fprintf(stderr, "syntax error near: %s\n\n", argv[ret]);
- if(ret == -2)
- fprintf(stderr, "memory error on options_parse, exitting\n");
- if(ret == -3)
+ if(ret == -1) {
options_print_version();
- if(ret == -4)
- fprintf(stderr, "the port number is invalid\n");
- if(ret == -5)
- fprintf(stderr, "the timeout value is invalid\n");
-
- if(ret != -2 && ret != -3 && ret != -4)
- options_print_usage();
-
- if(ret == -1 || ret == -3)
ret = 0;
-
+ }
options_clear(&opt);
log_close();
exit(ret);
}
- slist_element_t* tmp = opt.log_targets_.first_;
- while(tmp) {
- ret = log_add_target(tmp->data_);
+
+ 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*)(tmp->data_)); break;
- case -4: fprintf(stderr, "this log target is only allowed once: '%s', exitting\n", (char*)(tmp->data_)); break;
- default: fprintf(stderr, "syntax error near: '%s', exitting\n", (char*)(tmp->data_)); 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);
}
- tmp = tmp->next_;
}
log_printf(NOTICE, "just started...");
- options_parse_post(&opt);
if(opt.debug_)
options_print(&opt);
-
if(opt.appname_)
g_set_prgname (opt.appname_);
else
g_set_prgname (opt.progname_);
+ options_clear(&opt);
+ exit(0);
+
priv_info_t priv;
if(opt.username_)
if(priv_init(&priv, opt.username_, opt.groupname_)) {
@@ -311,7 +300,6 @@ int main(int argc, char* argv[])
fclose(pid_file);
}
- gst_init(NULL, NULL);
const gchar *nano_str;
guint major, minor, micro, nano;
gst_version(&major, &minor, &micro, &nano);