121#define MOD_NAME "[main] "
122#define PORT_BASE 5004
127#define OPT_AUDIO_CAPTURE_CHANNELS (('a' << 8) | 'c')
128#define OPT_AUDIO_DELAY (('A' << 8) | 'D')
129#define OPT_AUDIO_HOST (('A' << 8) | 'H')
130#define OPT_AUDIO_PROTOCOL (('A' << 8) | 'P')
131#define OPT_AUDIO_SCALE (('a' << 8) | 's')
132#define OPT_CONTROL_PORT (('C' << 8) | 'P')
133#define OPT_ECHO_CANCELLATION (('E' << 8) | 'C')
134#define OPT_MCAST_IF (('M' << 8) | 'I')
135#define OPT_PIX_FMTS (('P' << 8) | 'F')
136#define OPT_PIXFMT_CONV_POLICY (('P' << 8) | 'C')
137#define OPT_RTSP_SERVER (('R' << 8) | 'S')
138#define OPT_VIDEO_CODECS (('V' << 8) | 'C')
139#define OPT_VIDEO_PROTOCOL (('V' << 8) | 'P')
140#define OPT_WINDOW_TITLE (('W' << 8) | 'T')
142#define MAX_CAPTURE_COUNT 17
145using namespace std::chrono;
168 s->should_exit_capture =
true;
177 if (signum == SIGPIPE) {
178 signal(SIGPIPE, SIG_IGN);
184 char *ptr_end = buf +
sizeof buf;
185 strappend(&ptr, ptr_end,
"Caught signal ");
186 if (signum / 10 != 0) {
187 *ptr++ = (char) (
'0' + signum / 10);
189 *ptr++ = (char) (
'0' + signum % 10);
192 write_all(STDERR_FILENO, ptr - buf, buf);
202 for (
auto const &line : help) {
203 int spaces = help_lines == 0 ? 31 - (int)
name.length() : 39;
204 for (
int i = 0; i <
max(spaces, 0) + 1; ++i) {
207 cout << line <<
"\n";
211 if (help_lines == 0) {
217static void usage(
const char *exec_path,
bool full =
false)
219 col() <<
"Usage: " <<
SBOLD(
SRED((exec_path ? exec_path :
"<executable_path>")) <<
" [options] address\n\n");
220 printf(
"Options:\n");
222 print_help_item(
"-d <display_device>", {
"select display device, use '-d help'",
223 "to get list of supported devices"});
224 print_help_item(
"-t <capture_device>", {
"select capture device, use '-t help'",
225 "to get list of supported devices"});
227 print_help_item(
"-r <playback_device>", {
"audio playback device (see '-r help')"});
228 print_help_item(
"-s <capture_device>", {
"audio capture device (see '-s help')"});
231 "-V, --verbose[=<level>]",
232 {
"print verbose messages (optionally specify level [0-" +
236 "connection types: 0- Server (default), 1- Client"});
237 print_help_item(
"-x, --protocol <proto>", {
"transmission protocol to use (see `-x help`)"});
241 print_help_item(
"--mcast-if <iface>", {
"bind to specified interface for multicast"});
242 print_help_item(
"-m <mtu>", {
"set path MTU assumption towards receiver"});
243 print_help_item(
"-M <video_mode>", {
"received video mode (eg tiled-4K, 3D,",
245 print_help_item(
"-N, --nat-traverse"s, {
"try to deploy NAT traversal techniques"s});
247 print_help_item(
"-T, --ttl <num>", {
"Use specified TTL for multicast/unicast (0..255, -1 for default)"});
249 print_help_item(
"-f [A:|V:]<settings>", {
"FEC settings (audio or video) - use",
250 "\"none\", \"mult:<nr>\",",
"\"ldgm:<max_expected_loss>%\" or",
"\"ldgm:<k>:<m>:<c>\"",
253 print_help_item(
"-P <port> | <video_rx>:<video_tx>[:<audio_rx>:<audio_tx>]", {
"",
254 "<port> is base port number, also 3",
255 "subsequent ports can be used for RTCP",
256 "and audio streams. Default: " + to_string(
PORT_BASE) +
".",
257 "You can also specify all two or four",
"ports directly."});
258 print_help_item(
"-l <limit_bitrate> | unlimited | auto", {
"limit sending bitrate",
259 "to <limit_bitrate> (with optional k/M/G suffix)"});
260 print_help_item(
"--audio-host <address>", {
"audio destination address",
261 "If not specified, will use same as for video"});
263 print_help_item(
"-a, --audio-capture-format <fmt> | help", {
"format of captured audio"});
266 print_help_item(
"--audio-filter <filter>[:<config>][#<filter>[:<config>]]...", {});
269 "<codec>[:sample_rate=<sr>][:bitrate=<br>] | help",
272 print_help_item(
"--audio-delay <delay_ms>", {
"amount of time audio should be delayed to video",
273 "(may be also negative to delay video)"});
275 {
"scales received audio"});
276 print_help_item(
"--echo-cancellation", {
"apply acoustic echo cancellation to audio (experimental)"});
277 print_help_item(
"-D, --cuda-device <index> | help", {
"use specified GPU"});
278 print_help_item(
"-e, --encryption <passphrase>", {
"key material for encryption"});
279 print_help_item(
"-I, --playback <directory> | help", {
"replays recorded audio and video"});
280 print_help_item(
"-E, --record[=<directory>]", {
"record captured audio and video"});
282 {
"capture filter, must precede -t if more device used"});
283 print_help_item(
"--param <params> | help", {
"additional advanced parameters, use help for list"});
285 print_help_item(
"--conv-policy [cds]{3} | help", {
"pixel format conversion policy"});
293print_fps(
const char *prefix, steady_clock::time_point *t0,
int *frames,
297 MIN_FPS_PERC_WARN = 98,
298 MIN_FPS_PERC_WARN2 = 90,
300 if (prefix ==
nullptr) {
304 steady_clock::time_point t1 = steady_clock::now();
305 double seconds = duration_cast<duration<double>>(t1 - *t0).
count();
309 const double fps = *frames / seconds;
310 const int fps_perc = (int) floor(fps / nominal_fps * 100.);
311 const char *fps_col = fps_perc >= MIN_FPS_PERC_WARN ?
""
312 : fps_perc >= MIN_FPS_PERC_WARN2
319 prefix, *frames, seconds, fps_col, fps);
337 steady_clock::time_point t0 = steady_clock::now();
339 const char *print_fps_prefix =
342 while (!
uv->should_exit_capture) {
347 if (
audio !=
nullptr) {
352 if (tx_frame ==
nullptr) {
355 print_fps(print_fps_prefix, &t0, &frames, tx_frame->
fps);
357 bool wait_for_cur_uncompressed_frame =
false;
358 shared_ptr<video_frame>
frame;
361 wait_for_cur_uncompressed_frame =
true;
362 frame = shared_ptr<video_frame>(
367 frame = shared_ptr<video_frame>(
371 uv->state_video_rxtx->send(
377 if (wait_for_cur_uncompressed_frame) {
393 if(strcmp(
"help", optarg) == 0) {
398 return -EXIT_FAILURE;
401 char *
item, *save_ptr = NULL;
403 while((
item = strtok_r(optarg,
",", &save_ptr))) {
406 return -EXIT_FAILURE;
419 sv.copy(dest,
N - 1);
424 std::string_view sv = conf;
431 col() <<
"Usage:\n" <<
432 "\tuv " <<
TBOLD(
"-Nholepunch:room=<room>:(server=<host> | coord_srv=<host:port>:stun_srv=<host:port>)[:client_name=<name>][:bind_ip=<addr>] \n") <<
434 "\t\t" <<
TBOLD(
"server") <<
" - used if both stun & coord server are on the same host on standard ports (3478, 12558)\n"
435 "\t\t" <<
TBOLD(
"room") <<
" - name of room to join\n"
436 "\t\t" <<
TBOLD(
"client_name") <<
" - name to identify as to the coord server, if not specified hostname is used\n"
437 "\t\t" <<
TBOLD(
"bind_ip") <<
" - local ip to bind to\n"
442 if(
key ==
"coord_srv"){
455 }
else if(
key ==
"stun_srv"){
468 }
else if(
key ==
"server"){
474 }
else if(
key ==
"room"){
476 }
else if(
key ==
"client_name"){
478 }
else if(
key ==
"bind_ip"){
551 if (strcmp(optarg,
"help") == 0 || strcmp(optarg,
"fullhelp") == 0) {
559 "allowed for video-attached audio "
560 "connection (AESEBU/analog/embedded).\n");
572 char *save_ptr =
nullptr;
573 char *first_val = strtok_r(optarg,
":", &save_ptr);
574 if (first_val ==
nullptr || strcmp(first_val,
"help") == 0) {
578 if (
char *tx_port_str = strtok_r(
nullptr,
":", &save_ptr)) {
582 if ((tok = strtok_r(
nullptr,
":", &save_ptr)) !=
nullptr) {
584 if ((tok = strtok_r(
nullptr,
":", &save_ptr)) !=
nullptr) {
592 opt->
port_base = stoi(first_val,
nullptr, 0);
603 bool set_audio =
true;
604 bool set_video =
true;
605 if (strlen(optarg) > 2 && optarg[1] ==
':') {
606 set_audio = toupper(optarg[0]) ==
'A';
607 set_video = toupper(optarg[0]) ==
'V';
608 if (!set_audio && !set_video) {
614 char *proto = optarg;
615 const char *cfg =
"";
616 if (strchr(optarg,
':')) {
617 char *delim = strchr(optarg,
':');
631 if (strcmp(optarg,
"help") == 0 ||
632 strcmp(optarg,
"fullhelp") == 0) {
633 col() <<
"Specify a transmission protocol.\nUsage:\n";
634 col() <<
SBOLD(
"\t-x proto")
" - use common protocol for audio and video\n";
635 col() <<
SBOLD(
"\t-x A:proto")
" - use specified audio protocol\n";
636 col() <<
SBOLD(
"\t-x V:proto")
" - use specified audio protocol\n";
655 if (strchr(optarg,
':')) {
656 char *save_ptr = NULL;
658 opt->
control_port = atoi(strtok_r(optarg,
":", &save_ptr));
665 if ((tok = strtok_r(NULL,
":", &save_ptr))) {
684 static struct option getopt_options[] = {
685 {
"audio-capture-format", required_argument,
nullptr,
'a'},
686 {
"capabilities", optional_argument,
nullptr,
'b'},
687 {
"compress", required_argument,
nullptr,
'c'},
688 {
"display", required_argument,
nullptr,
'd'},
689 {
"encryption", required_argument,
nullptr,
'e'},
690 {
"fec", required_argument,
nullptr,
'f'},
691 {
"help", no_argument,
nullptr,
'h'},
692 {
"audio-filter", required_argument,
nullptr,
'i'},
693 {
"limit-bitrate", required_argument,
nullptr,
'l'},
694 {
"capture", required_argument,
nullptr,
't'},
695 {
"mtu", required_argument,
nullptr,
'm'},
696 {
"postprocess", required_argument,
nullptr,
'p'},
697 {
"receive", required_argument,
nullptr,
'r'},
698 {
"send", required_argument,
nullptr,
's'},
699 {
"version", no_argument,
nullptr,
'v'},
700 {
"protocol", required_argument,
nullptr,
'x'},
701 {
"audio-codec", required_argument,
nullptr,
'A'},
702 {
"client", no_argument,
nullptr,
'C'},
703 {
"cuda-device", required_argument,
nullptr,
'D'},
704 {
"record", optional_argument,
nullptr,
'E'},
705 {
"capture-filter", required_argument,
nullptr,
'F'},
706 {
"fullhelp", no_argument,
nullptr,
'H'},
707 {
"playback", required_argument,
nullptr,
'I'},
708 {
"list-modules", no_argument,
nullptr,
'L'},
709 {
"mode", required_argument,
nullptr,
'M'},
710 {
"nat-traverse", optional_argument,
nullptr,
'N'},
711 {
"param", required_argument,
nullptr,
'O'},
712 {
"port", required_argument,
nullptr,
'P'},
713 {
"server", no_argument,
nullptr,
'S'},
714 {
"ttl", required_argument,
nullptr,
'T'},
715 {
"audio-channel-map", required_argument,
nullptr,
'U'},
716 {
"verbose", optional_argument,
nullptr,
'V'},
733 const char *optstring =
734 "46A:CD:E::F:HI:LM:N::O:P:ST:U:Va:b::c:e:f:d:hi:l:m:p:r:s:t:vx:";
738 getopt_long(argc, argv, optstring, getopt_options,
742 if (strcmp(optarg,
"help") == 0 || strcmp(optarg,
"fullhelp") == 0) {
751 if(strchr(optarg,
':')) {
752 char *delim = strchr(optarg,
':');
758 if (strcmp(optarg,
"help") == 0 || strcmp(optarg,
"fullhelp") == 0) {
768 optarg[strlen(optarg) - 1] !=
'!') {
770 "MTU %1$u seems to be too low, use "
771 "\"%1$u!\" to force.\n",
793 "is deprecated and will be removed in future.\n"
794 "Please use \"-x rtsp[:args]\"instead.\n");
806 if (strcmp(optarg,
"help") == 0 || strcmp(optarg,
"fullhelp") == 0) {
822 if(strlen(optarg) > 2 && optarg[1] ==
':' &&
823 (toupper(optarg[0]) ==
'A' || toupper(optarg[0]) ==
'V')) {
824 if(toupper(optarg[0]) ==
'A') {
847 return -EXIT_FAILURE;
865 "Use \"-a channels=<count>\" instead.\n");
907 char dev_string[1024];
917 if(strcmp(optarg,
"help") == 0) {
945 "--param window-title=<title>\n");
1015 }
catch (logic_error &e) {
1019 if (
dynamic_cast<invalid_argument *
>(&e) !=
nullptr) {
1022 <<
"Non-numeric value passed to option "
1023 "expecting a number!\n";
1024 }
else if (
dynamic_cast<out_of_range *
>(&e) !=
nullptr) {
1026 <<
MOD_NAME <<
"Passed value is out of bounds!\n";
1035 unsigned int audio_rxtx_mode = 0;
1093 const bool tx_audio_std = strcasecmp(opt->
audio.
proto,
"rtsp") == 0 ||
1105#ifndef HAVE_LIBJUICE
1107 return EXIT_FAILURE;
1109 static char punched_host[512];
1113 return EXIT_FAILURE;
1146 return EXIT_FAILURE;
1149 if(!punch_fcn(&punch_c)){
1151 return EXIT_FAILURE;
1241 LOG(
LOG_LEVEL_WARNING) <<
"Using RTSP for video but not for audio is not recommended. Consider adding '--audio-protocol rtsp'.\n";
1245 LOG(
LOG_LEVEL_WARNING) <<
"Using RTSP for audio but not for video is not recommended and might not work.\n";
1251#define EXIT(expr) { int rc = expr; common_cleanup(init); return rc; }
1257#if defined HAVE_SCHED_SETSCHEDULER && defined USE_RT
1258 struct sched_param sp;
1262 pthread_t receiver_thread_id,
1264 bool receiver_thread_started =
false,
1265 capture_thread_started =
false;
1266 unsigned display_flags = 0;
1295 EXIT(ret < 0 ? -ret : EXIT_SUCCESS);
1303 if (ac_params.codec ==
AC_NONE) {
1307 col() <<
TBOLD(
"Display device : ") << opt.requested_display <<
"\n";
1309 col() <<
TBOLD(
"Audio capture : ") << opt.audio.send_cfg <<
"\n";
1310 col() <<
TBOLD(
"Audio playback : ") << opt.audio.recv_cfg <<
"\n";
1311 col() <<
TBOLD(
"MTU : ") << opt.common.mtu <<
" B\n";
1312 col() <<
TBOLD(
"Video compression: ") << opt.requested_compression <<
"\n";
1316 col() <<
TBOLD(
"Audio FEC : ") << opt.audio.fec_cfg <<
"\n";
1317 col() <<
TBOLD(
"Video FEC : ") << opt.requested_video_fec <<
"\n";
1321 opt.common.parent = &
uv.root_module;
1323 opt.common.exporter =
export_init(&
uv.root_module, opt.export_opts, opt.should_export);
1324 if (!opt.common.exporter) {
1329 if (
control_init(opt.control_port, opt.connection_type, &control,
1335 if(!opt.nat_traverse_config
1336 || strncmp(opt.nat_traverse_config,
"holepunch", strlen(
"holepunch")) != 0){
1337 nat_traverse =
start_nat_traverse(opt.nat_traverse_config, opt.requested_receiver, opt.video_rx_port, opt.audio.recv_port);
1357 printf(
"Unable to open display device: %s\n",
1358 opt.requested_display);
1361 }
else if(ret > 0) {
1369 printf(
"Unable to open capture device: %s\n",
1373 }
else if(ret > 0) {
1387#ifdef HAVE_SCHED_SETSCHEDULER
1388 sp.sched_priority = sched_get_priority_max(SCHED_FIFO);
1389 if (sched_setscheduler(0, SCHED_FIFO, &sp) != 0) {
1390 printf(
"WARNING: Unable to set real-time scheduling\n");
1393 printf(
"WARNING: System does not support real-time scheduling\n");
1398 map<string, param_u>
params;
1401 params[
"compression"].str = opt.requested_compression;
1402 params[
"rxtx_mode"].i = opt.video_rxtx_mode;
1405 params[
"capture_device"].ptr = (opt.video_rxtx_mode &
MODE_SENDER) != 0U ?
uv.capture_device :
nullptr;
1406 params[
"display_device"].ptr = (opt.video_rxtx_mode &
MODE_RECEIVER) != 0U ?
uv.display_device :
nullptr;
1409 params[
"common"].cptr = &opt.common;
1410 params[
"receiver"].str = opt.requested_receiver;
1411 params[
"rx_port"].i = opt.video_rx_port;
1412 params[
"tx_port"].i = opt.video_tx_port;
1413 params[
"fec"].str = opt.requested_video_fec;
1414 params[
"bitrate"].ll = opt.bitrate;
1418 params[
"decoder_mode"].l = (long) opt.decoder_mode;
1419 params[
"display_device"].ptr =
uv.display_device;
1422 params[
"opts"].str = opt.video_protocol_opts;
1424 if (strcmp(opt.video_protocol,
"rtsp") == 0) {
1426 if ((strcmp(
"none", opt.audio.send_cfg) != 0)) {
1430 opt.vidcap_params_head)) != 0) {
1434 printf(
"[RTSP SERVER CHECK] no stream type... check capture devices input...\n");
1437 params[
"avType"].l = (long) avType;
1440 sdp_set_properties(opt.requested_receiver, opt.video_rxtx_mode &
MODE_SENDER && strcasecmp(opt.video_protocol,
"sdp") == 0, opt.audio.send_port != 0 && strcasecmp(opt.audio.proto,
"sdp") == 0);
1443 if (!
uv.state_video_rxtx) {
1444 if (strcmp(opt.video_protocol,
"help") != 0) {
1445 throw string(
"Requested RX/TX cannot be created (missing library?)");
1452 if (!
uv.state_video_rxtx->supports_receiving()) {
1453 fprintf(stderr,
"Selected RX/TX mode doesn't support receiving.\n");
1460 (
void *)
uv.state_video_rxtx) != 0) {
1461 perror(
"Unable to create display thread!\n");
1465 receiver_thread_started =
true;
1472 (
void *) &
uv) != 0) {
1473 perror(
"Unable to create capture thread!\n");
1477 capture_thread_started =
true;
1484 uv.state_video_rxtx,
1488 if (opt.requested_capabilities !=
nullptr) {
1506 }
catch (runtime_error
const &e) {
1509 }
catch (exception
const &e) {
1512 }
catch (
string const &str) {
1520 if (strcmp(
"none", opt.requested_display) != 0 &&
1521 receiver_thread_started)
1522 pthread_join(receiver_thread_id, NULL);
1525 && capture_thread_started) {
1526 pthread_join(capture_thread_id, NULL);
1531 if (
uv.state_video_rxtx)
1532 uv.state_video_rxtx->join();
1536 signal(SIGINT, SIG_DFL);
1537 signal(SIGTERM, SIG_DFL);
1539 signal(SIGHUP, SIG_DFL);
1546 delete uv.state_video_rxtx;
1548 if (
uv.capture_device)
1550 if (
uv.display_device)
struct video_frame * frame
struct audio_frame ** audio
#define AUDIO_FRAME_DISPOSE(frame)
void audio_register_aux_data(struct state_audio *s, struct additional_audio_data data)
unsigned int audio_get_display_flags(struct state_audio *s)
void audio_join(struct state_audio *s)
void audio_sdi_send(struct state_audio *s, struct audio_frame *frame)
void audio_done(struct state_audio *s)
int audio_init(struct state_audio **ret, const struct audio_options *opt, const struct common_opts *common)
void audio_start(struct state_audio *s)
unsigned int audio_capture_get_vidcap_flags(const char *const_device_name)
void audio_capture_print_help(bool full)
void audio_playback_help(bool full)
static af_result_code init(struct module *parent, const char *cfg, void **state)
struct audio_codec_params parse_audio_codec_params(const char *ccfg)
const char * get_name_to_audio_codec(audio_codec_t codec)
void list_audio_codecs(void)
int color_printf(const char *format,...)
#define TERM_FG_BRIGHT_GREEN
int control_init(int port, int connection_type, struct control_state **state, struct module *root_module, int force_ip_version)
void control_done(struct control_state *s)
void control_start(struct control_state *s)
static ssize_t write_all(fd_t fd, const void *buf, size_t count)
#define DEFAULT_CONTROL_PORT
void cuda_wrapper_print_devices_info(void)
adapted from gpujpeg_print_devices_info()
This file contais wrapper around CUDA functions.
void log_msg(int level, const char *format,...)
#define LOG_LEVEL_INFO
normal reporting
#define LOG_LEVEL_ERROR
general errors
#define LOG_LEVEL_VERBOSE
#define LOG_LEVEL_FATAL
errors that prevent UG run
#define LOG_LEVEL_WARNING
less severe errors
void export_destroy(struct exporter *s)
struct exporter * export_init(struct module *parent, const char *cfg, bool should_export)
bool display_reconfigure_audio(struct display *d, int quant_samples, int channels, int sample_rate)
void display_put_audio_frame(struct display *d, const struct audio_frame *frame)
Puts audio data.
void display_run_mainloop(struct display *d)
Display mainloop function.
bool display_ctl_property(struct display *d, int property, void *val, size_t *len)
Gets property from video display.
void display_done(struct display *d)
This function performs cleanup after done.
int initialize_video_display(struct module *parent, const char *requested_display, const char *fmt, unsigned int flags, const char *postprocess, struct display **out)
Initializes video display.
void list_video_display_devices(bool full)
void module_done(struct module *module_data)
void list_video_capture_devices(bool full)
struct video_frame * vidcap_grab(struct vidcap *state, struct audio_frame **audio)
Grabs video frame. This function may block for a short period if waiting for incoming frame....
int initialize_video_capture(struct module *parent, struct vidcap_params *param, struct vidcap **state)
Initializes video capture.
void vidcap_done(struct vidcap *state)
Destroys vidap state.
const char * vidcap_get_fps_print_prefix(struct vidcap *state)
void set_audio_delay(int audio_delay)
void crash_signal_handler(int sig)
void init_root_module(struct module *root_mod)
unsigned int cuda_devices_count
void print_capabilities(const char *cfg)
void register_should_exit_callback(struct module *mod, void(*callback)(void *), void *udata)
bool cuda_devices_explicit
ācuda-device/-D specified expilcitly
void print_configuration()
int get_exit_status(struct module *root_mod)
int set_pixfmt_conv_policy(const char *optarg)
std::unordered_map< std::string, std::string > commandline_params
unsigned int cuda_devices[MAX_CUDA_DEVICES]
bool tok_in_argv(char **argv, const char *tok)
bool parse_params(const char *optarg, bool preinit)
void hang_signal_handler(int sig)
bool parse_bitrate(char *optarg, long long int *bitrate)
static struct @19 params[100]
struct init_data * common_preinit(int argc, char *argv[])
void print_video_codecs(void)
int set_audio_capture_format(const char *optarg)
void print_pixel_formats(void)
unsigned int audio_capture_channels
void common_cleanup(struct init_data *init)
#define EXIT_FAIL_CAPTURE
#define RATE_DEFAULT
imaginary value, must not be passed to trasmit module
#define EXIT_FAIL_DISPLAY
#define EXIT_FAIL_CONTROL_SOCK
#define RATE_DYNAMIC
same as RATE_AUTO but occasional excess frame allowed
const void * load_library(const char *name, enum library_class cls, int abi_version)
@ LIBRARY_CLASS_UNDEFINED
#define snprintf_ch(str,...)
shortcut for snprintf(var, sizeof var...), var must be a char array
#define to_fourcc(a, b, c, d)
Creates FourCC word.
bool invalid_arg_is_numeric(const char *what)
void stop_nat_traverse(struct ug_nat_traverse *s)
struct ug_nat_traverse * start_nat_traverse(const char *config, const char *remote_host, int video_rx_port, int audio_rx_port)
bool is_host_loopback(const char *hostname)
bool is_ipv6_supported(void)
#define IN6_BLACKHOLE_SERVER_MODE_STR
int playback_set_device(char *device_string, size_t buf_len, const char *optarg)
void sdp_set_properties(const char *receiver, bool has_sdp_video, bool has_sdp_audio)
static void strappend(char **dst, size_t *dst_alloc_len, const char *src)
static void copy_sv_to_c_buf(char(&dest)[N], std::string_view sv)
#define OPT_ECHO_CANCELLATION
static bool parse_protocol(int ch, char *optarg, struct ug_options *opt)
static int parse_options_internal(int argc, char *argv[], struct ug_options *opt)
static bool parse_port(char *optarg, struct ug_options *opt)
#define OPT_VIDEO_PROTOCOL
static void * capture_thread(void *arg)
static int parse_options(int argc, char *argv[], struct ug_options *opt)
#define OPT_AUDIO_PROTOCOL
static constexpr const char * DEFAULT_VIDEO_COMPRESSION
static constexpr const char * DEFAULT_AUDIO_CODEC
static void print_fps(const char *prefix, steady_clock::time_point *t0, int *frames, double nominal_fps)
#define OPT_PIXFMT_CONV_POLICY
static int parse_audio_capture(struct ug_options *opt, char *optarg)
static void print_help_item(const string &name, const vector< string > &help)
static int parse_cuda_device(char *optarg)
static bool parse_holepunch_conf(char *conf, struct Holepunch_config *punch_c)
static bool parse_control_port(char *optarg, struct ug_options *opt)
static int adjust_params(struct ug_options *opt)
static void signal_handler(int signum)
#define OPT_AUDIO_CAPTURE_CHANNELS
void append_sig_desc(char **ptr, const char *ptr_end, int signum)
std::string_view tokenize(std::string_view &str, char delim, char quot)
Tokenizer for string_view.
bool parse_num(std::string_view sv, T &res, int base=10)
struct used to comunicate with audio capture/playback device
struct module * root_module
This struct represents initialized video display state.
struct state_audio * audio
struct module root_module
static constexpr uint32_t state_magic
struct display * display_device
static void should_exit_capture_callback(void *udata)
struct vidcap * capture_device
video_rxtx * state_video_rxtx
const char * video_protocol_opts
std::string audio_filter_cfg
const char * requested_display
struct vidcap_params * vidcap_params_head
const char * video_protocol
unsigned int video_rxtx_mode
const char * requested_compression
struct common_opts common
const char * requested_video_fec
const char * requested_receiver
struct vidcap_params * vidcap_params_tail
enum video_mode decoder_mode
struct audio_options audio
char * nat_traverse_config
const char * requested_capabilities
This struct represents video capture state.
void(* dispose)(struct video_frame *)
Struct video_frame represents a video frame and contains video description.
struct video_frame_callbacks callbacks
static video_rxtx * create(std::string const &name, std::map< std::string, param_u > const &)
static void * receiver_thread(void *arg)
static void list(bool full)
static const char * get_long_name(std::string const &short_name)
void set_thread_name(const char *name)
static struct timeval start_time
static time_ns_t get_time_in_ns()
@ VIDEO_UNKNOWN
unspecified video mode
@ VIDEO_NORMAL
normal video (one tile)
#define HOLEPUNCH_ABI_VERSION
enum video_mode get_video_mode_from_str(const char *requested_mode)
This is an umbrella header for video functions.
struct vidcap_params * vidcap_params_allocate_next(struct vidcap_params *curr)
const char * vidcap_params_get_capture_filter(const struct vidcap_params *params)
struct vidcap_params * vidcap_params_get_next(const struct vidcap_params *curr)
void vidcap_params_add_flags(struct vidcap_params *params, unsigned int flags)
void vidcap_params_free_struct(struct vidcap_params *buf)
const char * vidcap_params_get_driver(const struct vidcap_params *params)
void vidcap_params_set_capture_filter(struct vidcap_params *params, const char *req_capture_filter)
struct vidcap_params * vidcap_params_allocate(void)
void vidcap_params_set_device(struct vidcap_params *params, const char *config)
API for video compress drivers.
void wait_obj_reset(struct wait_obj *wait_obj)
void wait_obj_wait(struct wait_obj *wait_obj)
struct wait_obj * wait_obj_init()
void wait_obj_done(struct wait_obj *wait_obj)
void wait_obj_notify(struct wait_obj *wait_obj)