diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am index c56cb8fe3ab6f4d4418ac96cd2d966e4979a8a7f..9cdf98e0a1515e58550603148fc920ee4c57dc63 100644 --- a/modules/access/Makefile.am +++ b/modules/access/Makefile.am @@ -423,7 +423,7 @@ EXTRA_LTLIBRARIES += libaccess_mtp_plugin.la ### SRT ### -libaccess_srt_plugin_la_SOURCES = access/srt.c dummy.cpp +libaccess_srt_plugin_la_SOURCES = access/srt.c access/srt_common.c access/srt_common.h dummy.cpp libaccess_srt_plugin_la_CFLAGS = $(AM_CFLAGS) $(SRT_CFLAGS) libaccess_srt_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(SRT_CPPFLAGS) libaccess_srt_plugin_la_LIBADD = $(SRT_LIBS) diff --git a/modules/access/srt_common.c b/modules/access/srt_common.c new file mode 100644 index 0000000000000000000000000000000000000000..be6a9732cbeaf846ea04528f54bc1435bac1b364 --- /dev/null +++ b/modules/access/srt_common.c @@ -0,0 +1,168 @@ +/***************************************************************************** + * srt_common.c: SRT (Secure Reliable Transport) access module + ***************************************************************************** + * + * Copyright (C) 2019, Haivision Systems Inc. + * + * Author: Aaron Boxer <aaron.boxer@collabora.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ + +#include "srt_common.h" + +const char * const srt_key_length_names[] = { N_( "16 bytes" ), N_( + "24 bytes" ), N_( "32 bytes" ), }; + +typedef struct parsed_param { + char *key; + char *val; +} parsed_param_t; + +static inline char* +find(char *str, char find) +{ + str = strchr( str, find ); + return str != NULL ? str + 1 : NULL; +} + +/** + * Parse a query string into an array of key/value structs. + * + * The query string should be a null terminated string of parameters separated + * by a delimiter. Each parameter are checked for the equal sign character. + * If it appears in the parameter, it will be used as a null terminator + * and the part that comes after it will be the value of the parameter. + * + * + * param: query: the query string to parse. The string will be modified. + * param: delimiter: the character that separates the key/value pairs + * from each other. + * param: params: an array of parsed_param structs to hold the result. + * param: max_params: maximum number of parameters to parse. + * + * Return: the number of parsed items. -1 if there was an error. + */ +static int srt_url_parse_query(char *query, const char* delimiter, + parsed_param_t *params, int max_params) +{ + int i = 0; + char *token = NULL; + + if (!query || *query == '\0') + return -1; + if (!params || max_params == 0) + return 0; + + token = strtok( query, delimiter ); + while (token != NULL && i < max_params) { + params[i].key = token; + params[i].val = NULL; + if ((params[i].val = strchr( params[i].key, '=' )) != NULL) { + size_t val_len = strlen( params[i].val ); + + /* make key into a zero-delimited string */ + *(params[i].val) = '\0'; + + /* make sure val is not empty */ + if (val_len > 1) { + params[i].val++; + + /* make sure key is not empty */ + if (params[i].key[0]) + i++; + }; + } + token = strtok( NULL, delimiter ); + } + return i; +} + +bool srt_parse_url(char* url, srt_params_t* params) +{ + char* query = NULL; + struct parsed_param local_params[32]; + int num_params = 0; + int i = 0; + bool rc = false; + + if (!url || !url[0] || !params) + return false; + + /* initialize params */ + params->latency = -1; + params->passphrase = NULL; + params->key_length = -1; + params->payload_size = -1; + params->bandwidth_overhead_limit = -1; + + /* Parse URL parameters */ + query = find( url, '?' ); + if (query) { + num_params = srt_url_parse_query( query, "&", local_params, + sizeof(local_params) / sizeof(struct parsed_param) ); + if (num_params > 0) { + rc = true; + for (i = 0; i < num_params; ++i) { + char* val = local_params[i].val; + if (!val) + continue; + + if (strcmp( local_params[i].key, SRT_PARAM_LATENCY ) == 0) { + int temp = atoi( val ); + if (temp >= 0) + params->latency = temp; + } else if (strcmp( local_params[i].key, SRT_PARAM_PASSPHRASE ) + == 0) { + params->passphrase = val; + } else if (strcmp( local_params[i].key, SRT_PARAM_PAYLOAD_SIZE ) + == 0) { + int temp = atoi( val ); + if (temp >= 0) + params->payload_size = temp; + } else if (strcmp( local_params[i].key, SRT_PARAM_KEY_LENGTH ) + == 0) { + int temp = atoi( val ); + if (temp == srt_key_lengths[0] || temp == srt_key_lengths[1] + || temp == srt_key_lengths[2]) { + params->key_length = temp; + } + } else if (strcmp( local_params[i].key, + SRT_PARAM_BANDWIDTH_OVERHEAD_LIMIT ) == 0) { + int temp = atoi( val ); + if (temp >= 0) + params->bandwidth_overhead_limit = temp; + + } + } + } + } + + return rc; +} + +int srt_set_socket_option(vlc_object_t *this, const char *srt_param, + SRTSOCKET u, SRT_SOCKOPT opt, const void *optval, int optlen) +{ + int stat = 0; + + stat = srt_setsockopt( u, 0, opt, optval, optlen ); + if (stat) + msg_Err( this, "Failed to set socket option %s (reason: %s)", srt_param, + srt_getlasterror_str() ); + + return stat; +} + diff --git a/modules/access/srt_common.h b/modules/access/srt_common.h new file mode 100644 index 0000000000000000000000000000000000000000..c2322d5755552abadd5b3a767ba04f7e73b7a3eb --- /dev/null +++ b/modules/access/srt_common.h @@ -0,0 +1,78 @@ +/***************************************************************************** + * srt_common.h: SRT (Secure Reliable Transport) access module + ***************************************************************************** + * + * Copyright (C) 2019, Haivision Systems Inc. + * + * Author: Aaron Boxer <aaron.boxer@collabora.com> + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 2.1 of the License, or + * (at your option) any later version. + * + * This program 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 Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. + *****************************************************************************/ +#ifndef SRT_COMMON_H +#define SRT_COMMON_H 1 + +#ifdef HAVE_CONFIG_H +# include "config.h" +#endif + +#include <vlc_common.h> +#include <srt/srt.h> + + +/* SRT parameter names */ +#define SRT_PARAM_LATENCY "latency" +#define SRT_PARAM_PASSPHRASE "passphrase" +#define SRT_PARAM_PAYLOAD_SIZE "payload-size" +#define SRT_PARAM_BANDWIDTH_OVERHEAD_LIMIT "bandwidth-overhead-limit" +#define SRT_PARAM_CHUNK_SIZE "chunk-size" +#define SRT_PARAM_POLL_TIMEOUT "poll-timeout" +#define SRT_PARAM_KEY_LENGTH "key-length" + + +#define SRT_DEFAULT_BANDWIDTH_OVERHEAD_LIMIT 25 +/* libsrt defines default packet size as 1316 internally + * so srt module takes same value. */ +#define SRT_DEFAULT_CHUNK_SIZE SRT_LIVE_DEF_PLSIZE +/* libsrt tutorial uses 9000 as a default binding port */ +#define SRT_DEFAULT_PORT 9000 +/* Minimum/Maximum chunks to allow reading at a time from libsrt */ +#define SRT_MIN_CHUNKS_TRYREAD 10 +#define SRT_MAX_CHUNKS_TRYREAD 100 +/* The default timeout is -1 (infinite) */ +#define SRT_DEFAULT_POLL_TIMEOUT -1 +/* The default latency which srt library uses internally */ +#define SRT_DEFAULT_LATENCY SRT_LIVE_DEF_LATENCY_MS +#define SRT_DEFAULT_PAYLOAD_SIZE SRT_LIVE_DEF_PLSIZE +/* Crypto key length in bytes. */ +#define SRT_KEY_LENGTH_TEXT N_("Crypto key length in bytes") +#define SRT_DEFAULT_KEY_LENGTH 16 +static const int srt_key_lengths[] = { 16, 24, 32, }; + +extern const char * const srt_key_length_names[]; + +typedef struct srt_params { + int latency; + const char* passphrase; + int key_length; + int payload_size; + int bandwidth_overhead_limit; +} srt_params_t; + +bool srt_parse_url(char* url, srt_params_t* params); + +int srt_set_socket_option(vlc_object_t *this, const char *srt_param, + SRTSOCKET u, SRT_SOCKOPT opt, const void *optval, int optlen); + +#endif diff --git a/modules/access_output/Makefile.am b/modules/access_output/Makefile.am index 646bc46ee0ec62aa68b92bab08ddfb0e1388c2ee..224e93eee01b715ac800d4e47cceeaafc59e94ad 100644 --- a/modules/access_output/Makefile.am +++ b/modules/access_output/Makefile.am @@ -27,7 +27,7 @@ access_out_LTLIBRARIES += $(LTLIBaccess_output_shout) EXTRA_LTLIBRARIES += libaccess_output_shout_plugin.la ### SRT ### -libaccess_output_srt_plugin_la_SOURCES = access_output/srt.c dummy.cpp +libaccess_output_srt_plugin_la_SOURCES = access_output/srt.c access/srt_common.c access/srt_common.h dummy.cpp libaccess_output_srt_plugin_la_CFLAGS = $(AM_CFLAGS) $(SRT_CFLAGS) libaccess_output_srt_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) $(SRT_CPPFLAGS) libaccess_output_srt_plugin_la_LIBADD = $(SRT_LIBS) diff --git a/po/POTFILES.in b/po/POTFILES.in index c0d73027ab0a77f0fa62677e97ca2e950fc5001a..2436469829ababfccb17d5ff9369b003a682c1d1 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -213,6 +213,7 @@ modules/access/shm.c modules/access/smb_common.h modules/access/smb2.c modules/access/srt.c +modules/access/srt_common.c modules/access/tcp.c modules/access/timecode.c modules/access/udp.c