File: flags.cpp

package info (click to toggle)
nageru 2.3.2-1
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 3,120 kB
  • sloc: cpp: 39,131; perl: 94; sh: 18; makefile: 4
file content (155 lines) | stat: -rw-r--r-- 5,587 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
#include "flags.h"

#include <getopt.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <utility>

using namespace std;

Flags global_flags;
int flow_initialized_interpolation_quality;

// Long options that have no corresponding short option.
enum LongOption {
	OPTION_HELP = 1000,
	OPTION_SLOW_DOWN_INPUT = 1001,
	OPTION_HTTP_PORT = 1002,
	OPTION_TALLY_URL = 1003,
	OPTION_CUE_IN_POINT_PADDING = 1004,
	OPTION_CUE_OUT_POINT_PADDING = 1005,
	OPTION_MIDI_MAPPING = 1006
};

void usage()
{
	fprintf(stderr, "Usage: futatabi [OPTION]... SOURCE_URL\n");
	fprintf(stderr, "\n");
	fprintf(stderr, "      --help                      print usage information\n");
	fprintf(stderr, "  -w, --width                     output width in pixels (default 1280)\n");
	fprintf(stderr, "  -h, --height                    output height in pixels (default 720)\n");
	fprintf(stderr, "  -r, --frame-rate NUM[/NUM]      output frame rate, as a float or fraction\n");
	fprintf(stderr, "                                    (default 60000/1001 ~= 59.94)\n");
	fprintf(stderr, "      --slow-down-input           slow down input to realtime (default on if no\n");
	fprintf(stderr, "                                    source URL given)\n");
	fprintf(stderr, "  -q, --interpolation-quality N   0 = off\n");
	fprintf(stderr, "                                  1 = fastest\n");
	fprintf(stderr, "                                  2 = default (realtime 720p on fast embedded GPUs)\n");
	fprintf(stderr, "                                  3 = good (realtime 720p on GTX 970 or so)\n");
	fprintf(stderr, "                                  4 = best (not realtime on any current GPU)\n");
	fprintf(stderr, "      --cue-in-point-padding SECS   move cue-in N seconds earlier on set\n");
	fprintf(stderr, "      --cue-out-point-padding SECS  move cue-out N seconds later on set\n");
	fprintf(stderr, "  -d, --working-directory DIR     where to store frames and database\n");
	fprintf(stderr, "      --http-port PORT            which port to listen on for output\n");
	fprintf(stderr, "      --tally-url URL             URL to get tally color from (polled every 100 ms)\n");
	fprintf(stderr, "      --midi-mapping=FILE         start with the given MIDI controller mapping\n");
	fprintf(stderr, "  -l  --source-label NUM:LABEL    label source NUM as LABEL, if visible\n");
}

void parse_flags(int argc, char *const argv[])
{
	static const option long_options[] = {
		{ "help", no_argument, 0, OPTION_HELP },
		{ "width", required_argument, 0, 'w' },
		{ "height", required_argument, 0, 'h' },
		{ "frame-rate", required_argument, 0, 'r' },
		{ "slow-down-input", no_argument, 0, OPTION_SLOW_DOWN_INPUT },
		{ "interpolation-quality", required_argument, 0, 'q' },
		{ "working-directory", required_argument, 0, 'd' },
		{ "http-port", required_argument, 0, OPTION_HTTP_PORT },
		{ "tally-url", required_argument, 0, OPTION_TALLY_URL },
		{ "cue-in-point-padding", required_argument, 0, OPTION_CUE_IN_POINT_PADDING },
		{ "cue-out-point-padding", required_argument, 0, OPTION_CUE_OUT_POINT_PADDING },
		{ "midi-mapping", required_argument, 0, OPTION_MIDI_MAPPING },
		{ "source-label", required_argument, 0, 'l' },
		{ 0, 0, 0, 0 }
	};
	for (;;) {
		int option_index = 0;
		int c = getopt_long(argc, argv, "w:h:r:q:d:l:", long_options, &option_index);

		if (c == -1) {
			break;
		}
		switch (c) {
		case 'w':
			global_flags.width = atoi(optarg);
			break;
		case 'h':
			global_flags.height = atoi(optarg);
			break;
		case 'r': {
			double num, den;
			if (sscanf(optarg, "%lf/%lf", &num, &den) == 2) {
				global_flags.output_framerate = num / den;
			} else if (sscanf(optarg, "%lf", &num) == 1) {
				global_flags.output_framerate = num;
			} else {
				fprintf(stderr, "Invalid frame rate given (must be on the form N or N/M)\n");
				exit(1);
			}
			break;
		}
		case OPTION_SLOW_DOWN_INPUT:
			global_flags.slow_down_input = true;
			break;
		case 'q':
			global_flags.interpolation_quality = atoi(optarg);
			global_flags.interpolation_quality_set = true;
			break;
		case 'd':
			global_flags.working_directory = optarg;
			break;
		case 'l': {
			int prefix_len;
			unsigned channel_idx;
			if (sscanf(optarg, "%u:%n", &channel_idx, &prefix_len) == 1) {
				const char *label = optarg + prefix_len;
				global_flags.source_labels[channel_idx] = label;
			} else {
				fprintf(stderr, "Invalid source label format (must be on the form NUM:LABEL)\n");
				exit(1);
			}
			break;
		}
		case OPTION_HTTP_PORT:
			global_flags.http_port = atoi(optarg);
			break;
		case OPTION_TALLY_URL:
			global_flags.tally_url = optarg;
			break;
		case OPTION_CUE_IN_POINT_PADDING:
			global_flags.cue_in_point_padding_seconds = atof(optarg);
			global_flags.cue_in_point_padding_set = true;
			break;
		case OPTION_CUE_OUT_POINT_PADDING:
			global_flags.cue_out_point_padding_seconds = atof(optarg);
			global_flags.cue_out_point_padding_set = true;
			break;
		case OPTION_MIDI_MAPPING:
			global_flags.midi_mapping_filename = optarg;
			break;
		case OPTION_HELP:
			usage();
			exit(0);
		default:
			fprintf(stderr, "Unknown option '%s'\n", argv[option_index]);
			fprintf(stderr, "\n");
			usage();
			exit(1);
		}
	}

	if (global_flags.interpolation_quality < 0 || global_flags.interpolation_quality > 4) {
		fprintf(stderr, "Interpolation quality must be 0, 1, 2, 3 or 4.\n");
		usage();
		exit(1);
	}
	if (global_flags.cue_in_point_padding_seconds < 0.0 ||
	    global_flags.cue_out_point_padding_seconds < 0.0) {
		fprintf(stderr, "Cue point padding cannot be negative.\n");
		usage();
		exit(1);
	}
}