diff options
author | Christian Pointner <equinox@spreadspace.org> | 2014-09-26 00:29:10 +0200 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2014-09-26 00:29:10 +0200 |
commit | a32b141e1c7bbdc5e36e9d3debf262eb1c26ddfc (patch) | |
tree | ff8b802b606ccb88ebff1db1110a23595d66aa16 /src | |
parent | improved default pipeline (diff) |
now using GOptions for command line parsing
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/options.c | 462 | ||||
-rw-r--r-- | src/options.h | 55 | ||||
-rw-r--r-- | src/slist.c | 138 | ||||
-rw-r--r-- | src/slist.h | 59 | ||||
-rw-r--r-- | src/string_list.c | 77 | ||||
-rw-r--r-- | src/string_list.h | 49 | ||||
-rw-r--r-- | src/sydra.c | 40 |
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, µ, &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, µ, &nano); |