summaryrefslogtreecommitdiff
path: root/src/options.c
diff options
context:
space:
mode:
authorChristian Pointner <equinox@spreadspace.org>2014-10-07 23:21:34 +0200
committerChristian Pointner <equinox@spreadspace.org>2014-10-07 23:21:34 +0200
commit93097a178c6d0d50cbcfdf26a1a63fd571138484 (patch)
tree0919df4cbd5660b0ec32132cf0e4fad38aa62210 /src/options.c
parentprepared build system for multiple binaries (diff)
cleanup for multiple binaries
Diffstat (limited to 'src/options.c')
-rw-r--r--src/options.c460
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, &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(" 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_);
-}