diff options
author | Christian Pointner <equinox@spreadspace.org> | 2014-10-07 23:21:34 +0200 |
---|---|---|
committer | Christian Pointner <equinox@spreadspace.org> | 2014-10-07 23:21:34 +0200 |
commit | 93097a178c6d0d50cbcfdf26a1a63fd571138484 (patch) | |
tree | 0919df4cbd5660b0ec32132cf0e4fad38aa62210 /src/options.c | |
parent | prepared build system for multiple binaries (diff) |
cleanup for multiple binaries
Diffstat (limited to 'src/options.c')
-rw-r--r-- | src/options.c | 460 |
1 files changed, 0 insertions, 460 deletions
diff --git a/src/options.c b/src/options.c deleted file mode 100644 index 9361759..0000000 --- a/src/options.c +++ /dev/null @@ -1,460 +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. - * - * - * 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-rtp.h" - -#include "options.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->mode_ = SENDER; - - opt->source_ = g_strdup("v4l2src ! videoconvert ! videoscale ! video/x-raw,format=I420,width=864,height=480,framerate=25/1,pixel-aspect-ratio=1/1 ! identity name=\"videosrc\" " \ - "autoaudiosrc ! audio/x-raw,format=S16LE,channels=1,rate=48000 ! identity name=\"audiosrc\""); - opt->sink_ = g_strdup("videoconvert name=\"videosink\" ! videoscale add-borders=true ! xvimagesink " \ - "audioconvert name=\"audiosink\" ! autoaudiosink"); - - 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->video_caps_ = g_strdup("application/x-rtp,media=video,clock-rate=90000,encoding-name=VP8-DRAFT-IETF-01,caps=\"video/x-vp8\""); - opt->video_depayloader_ = g_strdup("rtpvp8depay"); - opt->video_dec_ = g_strdup("vp8dec"); - - opt->audio_enc_ = g_strdup("opusenc bitrate=64000 cbr=true packet-loss-percentage=0 inband-fec=false"); - opt->audio_payloader_ = g_strdup("rtpopuspay"); - opt->audio_caps_ = g_strdup("application/x-rtp,media=audio,clock-rate=48000,payload=96,encoding-name=X-GST-OPUS-DRAFT-SPITTKA-00,caps=\"audio/x-opus\""); - opt->audio_depayloader_ = g_strdup("rtpopusdepay"); - opt->audio_dec_ = g_strdup("opusdec"); - - opt->rtp_host_ = NULL; - opt->rtp_port_base_ = 5000; - opt->rtp_addr_local_ = NULL; - opt->rtp_port_base_local_ = 5000; - opt->rtp_host_reflector_ = NULL; - opt->rtp_port_base_reflector_ = 6000; - opt->auto_client_ = TRUE; - opt->timeout_ = 30; - opt->keepalive_int_ = 10; - - opt->preview_videosink_ = NULL; - - opt->video_enc_rec_ = NULL; - opt->audio_enc_rec_ = NULL; - opt->rec_mux_ = NULL; - opt->rec_name_format_ = g_strdup("./recordings/%Y-%m-%d_%H-%M-%S"); -} - -static GQuark options_error_quark() -{ - static GQuark quark = 0; - if (!quark) - quark = g_quark_from_static_string("sydra_options_error"); - - return quark; -} - -static GOptionGroup* options_get_avsend_group(options_t* opt) -{ - GOptionEntry avsend_entries[] = { - { "source", 0, 0, G_OPTION_ARG_STRING, &opt->source_, - "pipeline for raw video and audio", "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" }, - { "previewsink", 0, 0, G_OPTION_ARG_STRING, &opt->preview_videosink_, - "video sink element for local preview (i.e. textoverlay text=\" preview \" ! xvimagesink) - leave empty to disable preview", "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* avsend_group = g_option_group_new ("avsend", "Audio/Video Sender Options", - "Show Audio/Video Sender Options", opt, NULL); - if(!avsend_group) return NULL; - g_option_group_add_entries(avsend_group, avsend_entries); - - return avsend_group; -} - -static GOptionGroup* options_get_avrecv_group(options_t* opt) -{ - GOptionEntry avrecv_entries[] = { - { "video-caps", 0, 0, G_OPTION_ARG_STRING, &opt->video_caps_, - "Caps for incoming Video RTP packets", "CAPS" }, - { "video-depayloader", 0, 0, G_OPTION_ARG_STRING, &opt->video_depayloader_, - "video RTP depayloader element (i.e. rtpvp8depay)", "ELEMENT" }, - { "video-decoder", 0, 0, G_OPTION_ARG_STRING, &opt->video_dec_, - "pipeline for video decoder (i.e. vp8dec)", "BIN DESCRIPTION" }, - { "audio-caps", 0, 0, G_OPTION_ARG_STRING, &opt->audio_caps_, - "Caps for incoming Audio RTP packets", "CAPS" }, - { "audio-depayloader", 0, 0, G_OPTION_ARG_STRING, &opt->audio_depayloader_, - "audio RTP depayloader element (i.e. rtpopusdepay)", "ELEMENT" }, - { "audio-decoder", 0, 0, G_OPTION_ARG_STRING, &opt->audio_dec_, - "pipeline for audio decoder (i.e. opusdnc)", "BIN DESCRIPTION" }, - { "sink", 0, 0, G_OPTION_ARG_STRING, &opt->sink_, - "video and audio sink bin", "BIN DESCRIPTION" }, - { NULL } - }; - GOptionGroup* avrecv_group = g_option_group_new ("avrecv", "Audio/Video Receiver Options", - "Show Audio/Video Receiver Options", opt, NULL); - if(!avrecv_group) return NULL; - g_option_group_add_entries(avrecv_group, avrecv_entries); - - return avrecv_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" }, - { "rtp-host-reflector", 0, 0, G_OPTION_ARG_STRING, &opt->rtp_host_reflector_, - "remote host where incoming RTP packets should be reflected to - receiver mode only!", "HOST" }, - { "rtp-port-base-reflector", 0, 0, G_OPTION_ARG_INT, &opt->rtp_port_base_reflector_, - "base number for ports where incoming RTP packets should be reflected to - receiver mode only!", "PORT" }, - { "no-auto-client", 'c', G_OPTION_FLAG_REVERSE, G_OPTION_ARG_NONE, &opt->auto_client_, - "disable auto-detection for clients (aka. ignore incoming keepalives) - sender mode only!", NULL }, - { "timeout", 't', 0, G_OPTION_ARG_INT, &opt->timeout_, - "client timeout in seconds (0 means no timeout) - sender mode only!", "VALUE" }, - { "keepalive-interval", 'k', 0, G_OPTION_ARG_INT, &opt->keepalive_int_, - "interval in seconds for sending out keep alive messages (0 means no keep alives) - receiver mode only!", "VALUE" }, - { NULL } - }; - GOptionGroup* rtp_group = g_option_group_new ("rtp", "RTP Options", - "Show RTP Options", opt, 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 element 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", opt, NULL); - if(!rec_group) return NULL; - g_option_group_add_entries(rec_group, rec_entries); - - return rec_group; -} - -static gboolean options_parse_mode(const gchar *option_name, const gchar *value, gpointer data, GError **error) -{ - options_t* opt = (options_t*)data; - - if(!strcmp(value, "sender")) - opt->mode_ = SENDER; - else if(!strcmp(value, "receiver")) - opt->mode_ = RECEIVER; - else { - g_set_error(error, options_error_quark(), G_OPTION_ERROR_FAILED, - "Invalid value for mode parameter '%s' - allowed values are: sender, receiver", value); - return FALSE; - } - return TRUE; -} - -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" }, - { "mode", 'm', 0, G_OPTION_ARG_CALLBACK, options_parse_mode, - "the main operation mode", "(sender|receiver)" }, - { 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* avsend_group = options_get_avsend_group(opt); - GOptionGroup* avrecv_group = options_get_avrecv_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(!main_group || !avsend_group || !avrecv_group || !rtp_group || !rec_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, avsend_group); - g_option_context_add_group(ctx, avrecv_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("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->rtp_port_base_ < 1 || opt->rtp_port_base_ > 65535 || - opt->rtp_port_base_local_ < 1 || opt->rtp_port_base_local_ > 65535 || - opt->rtp_port_base_reflector_ < 1 || opt->rtp_port_base_reflector_ > 65535) { - printf("ERROR: Failed to initialize: rtp port is invalid\n"); - return -2; - } - - if(opt->timeout_ < 0) { - printf("ERROR: Failed to initialize: timeout is invalid\n"); - return -3; - } - if(opt->keepalive_int_ < 0) { - printf("ERROR: Failed to initialize: keep alive interval is invalid\n"); - return -3; - } - - if(opt->mode_ == SENDER) { - if(opt->rtp_host_ && opt->auto_client_) { - printf("WARNING: you have set a remote RTP host and the automatic client handling is enabled.\n" \ - " Please mind that the remote RTP host is always added as a receiver and it shouldn't be\n" \ - " configured to send keepalives. This would re-add the receiver to the list of clients\n" \ - " and as a result duplicate packages will be sent.\n" \ - " Also the remote RTP host is excluded from client timeout handling and remove requests\n" \ - " will get ignored.\n\n"); - } else if(!opt->rtp_host_ && !opt->auto_client_) { - printf("WARNING: both, the remote RTP host, as well as the automatic client detection are disabled\n" \ - " this means that no streaming will be done. Recording will work but this is most probably\n" \ - " not what you intended - please check your configuration.\n\n"); - } - - if(opt->rtp_host_reflector_) { - printf("WARNING: The mode of operation is set to sender and the RTP packet reflector has a remote\n" \ - " host configured. Mind that in sender mode the reflector will not be used!\n\n"); - } - } - 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-rtp,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->source_); - g_free(opt->sink_); - g_free(opt->video_enc_); - g_free(opt->video_payloader_); - g_free(opt->video_caps_); - g_free(opt->video_depayloader_); - g_free(opt->video_dec_); - g_free(opt->audio_enc_); - g_free(opt->audio_payloader_); - g_free(opt->audio_caps_); - g_free(opt->audio_depayloader_); - g_free(opt->audio_dec_); - g_free(opt->rtp_host_); - g_free(opt->rtp_addr_local_); - g_free(opt->rtp_host_reflector_); - 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); -#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, µ, &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(" mode: >>%s<<\n", opt->mode_ == SENDER ? "sender" : "receiver"); - printf(" source: >>%s<<\n", opt->source_); - printf(" sink: >>%s<<\n", opt->sink_); - printf(" video_enc: >>%s<<\n", opt->video_enc_); - printf(" video_payloader: >>%s<<\n", opt->video_payloader_); - printf(" video_caps: >>%s<<\n", opt->video_caps_); - printf(" video_depayloader: >>%s<<\n", opt->video_depayloader_); - printf(" video_dec: >>%s<<\n", opt->video_dec_); - printf(" audio_enc: >>%s<<\n", opt->audio_enc_); - printf(" audio_payloader: >>%s<<\n", opt->audio_payloader_); - printf(" audio_caps: >>%s<<\n", opt->audio_caps_); - printf(" audio_depayloader: >>%s<<\n", opt->audio_depayloader_); - printf(" audio_dec: >>%s<<\n", opt->audio_dec_); - printf(" rtp_host: >>%s<<\n", opt->rtp_host_); - printf(" rtp_port_base: %d\n", opt->rtp_port_base_); - printf(" rtp_addr_local: >>%s<<\n", opt->rtp_addr_local_); - printf(" rtp_port_base_local: %d\n", opt->rtp_port_base_local_); - printf(" rtp_host_reflector: >>%s<<\n", opt->rtp_host_reflector_); - printf(" rtp_port_base_reflector: %d\n", opt->rtp_port_base_reflector_); - printf(" auto_client: %s\n", opt->auto_client_ ? "true" : "false"); - printf(" timeout: %d\n", opt->timeout_); - printf(" keepalive_int: %d\n", opt->keepalive_int_); - printf(" preview_video_sink: >>%s<<\n", opt->preview_videosink_); - printf(" video_enc_rec: >>%s<<\n", opt->video_enc_rec_); - printf(" audio_enc_rec: >>%s<<\n", opt->audio_enc_rec_); - printf(" rec_mux: >>%s<<\n", opt->rec_mux_); - printf(" rec_name_format: '%s'\n", opt->rec_name_format_); -} |