[vlc-devel] [PATCH 2/3] srt: move common code to single file

Thomas Guillem thomas at gllm.fr
Mon Mar 18 15:34:11 CET 2019


On Mon, Mar 18, 2019, at 14:18, Aaron Boxer wrote:
> 1. code can be shared between access/srt.c and access_output/srt.c
> 2. created a URL parser for SRT parameters stored in URL
> ---
>  modules/access/Makefile.am | 2 +-
>  modules/access/srt_common.c | 179 ++++++++++++++++++++++++++++++
>  modules/access/srt_common.h | 103 +++++++++++++++++
>  modules/access_output/Makefile.am | 2 +-
>  4 files changed, 284 insertions(+), 2 deletions(-)
>  create mode 100644 modules/access/srt_common.c
>  create mode 100644 modules/access/srt_common.h
> 
> diff --git a/modules/access/Makefile.am b/modules/access/Makefile.am
> index c56cb8fe3a..9cdf98e0a1 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 0000000000..2f205c762a
> --- /dev/null
> +++ b/modules/access/srt_common.c
> @@ -0,0 +1,179 @@
> +/*****************************************************************************
> + * srt_common.c: SRT (Secure Reliable Transport) access module
> + *****************************************************************************
> + *
> + * Copyright (C) 2019, Haivision Systems Inc.
> + *
> + * Author: Aaron Boxer <aaron.boxer at 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->mode = NULL;
> + params->latency = -1;
> + params->passphrase = NULL;
> + params->payload_size = -1;
> + params->encryption = NULL;
> + 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_MODE ) == 0) {
> + if (strcmp( val, SRT_MODE_LISTENER ) == 0) {
> + params->mode = SRT_MODE_LISTENER;
> + } else if (strcmp( val, SRT_MODE_CALLER ) == 0) {
> + params->mode = SRT_MODE_CALLER;
> + } else if (strcmp( val, SRT_MODE_RENDEZVOUS ) == 0) {
> + params->mode = SRT_MODE_RENDEZVOUS;
> + }
> + } 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_ENCRYPTION )
> + == 0) {
> + if (strcmp( val, SRT_ENCRYPTION_AES128 ) == 0) {
> + params->mode = SRT_ENCRYPTION_AES128;
> + } else if (strcmp( val, SRT_ENCRYPTION_AES198 ) == 0) {
> + params->mode = SRT_ENCRYPTION_AES198;
> + } else if (strcmp( val, SRT_ENCRYPTION_AES256 ) == 0) {
> + params->mode = SRT_ENCRYPTION_AES256;
> + }
> + } 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 0000000000..f0728faf1c
> --- /dev/null
> +++ b/modules/access/srt_common.h
> @@ -0,0 +1,103 @@
> +/*****************************************************************************
> + * srt_common.h: SRT (Secure Reliable Transport) access module
> + *****************************************************************************
> + *
> + * Copyright (C) 2019, Haivision Systems Inc.
> + *
> + * Author: Aaron Boxer <aaron.boxer at 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 Parameters
> +
> + Mode: Listener, Caller, Rendezvous (Caller by default)
> + Latency in Milliseconds (default as SRT default)
> + Passphrase (optional)
> + PayloadSize in Bytes (1316/"7 TS frames" by default)
> + Encryption: None, AES128, AES192, AES256
> + Bandwidth Overhead Limit/Headroom (default as sRT default)
> +
> + */
> +
> +/* SRT parameter names */
> +#define SRT_PARAM_MODE "mode"
> +#define SRT_PARAM_LATENCY "latency"
> +#define SRT_PARAM_PASSPHRASE "passphrase"
> +#define SRT_PARAM_PAYLOAD_SIZE "payload-size"
> +#define SRT_PARAM_ENCRYPTION "encryption"
> +#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"
> +
> +/* SRT Modes */
> +#define SRT_MODE_LISTENER "listener"
> +#define SRT_MODE_CALLER "caller"
> +#define SRT_MODE_RENDEZVOUS "rendezvous"
> +
> +/* SRT Encryption */
> +#define SRT_ENCRYPTION_NONE "none"
> +#define SRT_ENCRYPTION_AES128 "aes128"
> +#define SRT_ENCRYPTION_AES198 "aes198"
> +#define SRT_ENCRYPTION_AES256 "aes256"
> +
> +#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")

Hello,
If your new code use translations ("N_"), you need to add your file in po/POTFILES.in

> +#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 {
> + const char* mode;
> + int latency;
> + const char* passphrase;
> + int payload_size;
> + const char* encryption;
> + 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 646bc46ee0..224e93eee0 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)
> -- 
> 2.17.1
> _______________________________________________
> vlc-devel mailing list
> To unsubscribe or modify your subscription options:
> https://mailman.videolan.org/listinfo/vlc-devel
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mailman.videolan.org/pipermail/vlc-devel/attachments/20190318/cecdf005/attachment.html>


More information about the vlc-devel mailing list