Discussion:
[libav-devel] [PATCH] Add Haivision Open SRT protocol
Luca Barbato
2018-03-21 07:41:30 UTC
Permalink
From: Sven Dueking <***@nablet.com>

protocol requires libsrt (https://github.com/Haivision/srt) to be
installed

Signed-off-by: Sven Dueking <***@nablet.com>
Signed-off-by: Luca Barbato <***@gentoo.org>
---

Here the patch with all the changes folded in, I'll push it tonight if
nobody has further comments.

configure | 5 +
doc/protocols.texi | 139 ++++++++++++
libavformat/Makefile | 1 +
libavformat/opensrt.c | 575 ++++++++++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
5 files changed, 721 insertions(+)
create mode 100644 libavformat/opensrt.c

diff --git a/configure b/configure
index 95e6006440..c966cd2572 100755
--- a/configure
+++ b/configure
@@ -229,6 +229,7 @@ External library support:
--enable-libxcb-xfixes X11 mouse rendering [auto]
--enable-libxvid MPEG-4 ASP video encoding
--enable-openssl crypto
+ --enable-libsrt enable Haivision Open SRT protocol [no]
--enable-zlib compression [autodetect]

The following libraries provide various hardware acceleration features:
@@ -1371,6 +1372,7 @@ EXTERNAL_LIBRARY_LIST="
libschroedinger
libsnappy
libspeex
+ libsrt
libtheora
libtwolame
libvorbis
@@ -2522,6 +2524,8 @@ librtmpt_protocol_deps="librtmp"
librtmpte_protocol_deps="librtmp"
mmsh_protocol_select="http_protocol"
mmst_protocol_select="network"
+opensrt_protocol_select="network"
+opensrt_protocol_deps="libsrt"
rtmp_protocol_conflict="librtmp_protocol"
rtmp_protocol_select="tcp_protocol"
rtmp_protocol_suggest="zlib"
@@ -4668,6 +4672,7 @@ enabled libopenjpeg && { check_lib libopenjpeg openjpeg.h opj_version -lop
require_pkg_config libopenjpeg libopenjpeg1 openjpeg.h opj_version -DOPJ_STATIC; }
enabled libopus && require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create
enabled libpulse && require_pkg_config libpulse libpulse-simple pulse/simple.h pa_simple_new
+enabled libsrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
enabled librtmp && require_pkg_config librtmp librtmp librtmp/rtmp.h RTMP_Socket
enabled libschroedinger && require_pkg_config libschroedinger schroedinger-1.0 schroedinger/schro.h schro_init
enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy
diff --git a/doc/protocols.texi b/doc/protocols.texi
index c136c74e41..56d43e9e8a 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -655,6 +655,145 @@ To play back the first stream announced on one the default IPv6 SAP multicast ad
avplay sap://[ff0e::2:7ffe]
@end example

+@section srt
+
+Haivision Secure Reliable Transport Protocol via libsrt.
+
+The supported syntax for a SRT url is:
+@example
+srt://@var{hostname}:@var{port}[?@var{options}]
+@end example
+
+@var{options} contains a list of &-separated options of the form
+@var{key}=@var{val}.
+
+or
+
+@example
+@var{options} srt://@var{hostname}:@var{port}
+@end example
+
+@var{options} contains a list of '-@var{key} @var{val}'
+options.
+
+This protocol accepts the following options.
+
+@table @option
+@item connect_timeout
+Connection timeout. SRT cannot connect for RTT > 1500 msec
+(2 handshake exchanges) with the default connect timeout of
+3 seconds. This option applies to the caller and rendezvous
+connection modes. The connect timeout is 10 times the value
+set for the rendezvous mode (which can be used as a
+workaround for this connection problem with earlier versions).
+
+@item fc=@var{bytes}
+Flight Flag Size (Window Size), in bytes. FC is actually an
+internal parameter and you should set it to not less than
+@option{recv_buffer_size} and @option{mss}. The default value
+is relatively large, therefore unless you set a very large receiver buffer,
+you do not need to change this option. Default value is 25600.
+
+@item inputbw=@var{bytes/seconds}
+Sender nominal input rate, in bytes per seconds. Used along with
+@option{oheadbw}, when @option{maxbw} is set to relative (0), to
+calculate maximum sending rate when recovery packets are sent
+along with main media stream:
+@option{inputbw} * (100 + @option{oheadbw}) / 100
+if @option{inputbw} is not set while @option{maxbw} is set to
+relative (0), the actual ctual input rate is evaluated inside
+the library. Default value is 0.
+
+@item iptos=@var{tos}
+IP Type of Service. Applies to sender only. Default value is 0xB8.
+
+@item ipttl=@var{ttl}
+IP Time To Live. Applies to sender only. Default value is 64.
+
+@item listen_timeout
+Set socket listen timeout.
+
+@item maxbw=@var{bytes/seconds}
+Maximum sending bandwidth, in bytes per seconds.
+-1 infinite (CSRTCC limit is 30mbps)
+0 relative to input rate (see @option{inputbw})
+>0 absolute limit value
+Default value is 0 (relative)
+
+@item mode=@var{caller|listener|rendezvous}
+Connection mode.
+caller opens client connection.
+listener starts server to listen for incoming connections.
+rendezvous use Rendez-Vous connection mode.
+Default valus is caller.
+
+@item mss=@var{bytes}
+Maximum Segment Size, in bytes. Used for buffer allocation
+and rate calculation using packet counter assuming fully
+filled packets. The smallest MSS between the peers is
+used. This is 1500 by default in the overall internet.
+This is the maximum size of the UDP packet and can be
+only decreased, unless you have some unusual dedicated
+network settings. Default value is 1500.
+
+@item nakreport=@var{1|0}
+If set to 1, Receiver will send `UMSG_LOSSREPORT` messages
+periodically until the lost packet is retransmitted or
+intentionally dropped. Default value is 1.
+
+@item oheadbw=@var{percents}
+Recovery bandwidth overhead above input rate, in percents.
+See @option{inputbw}. Default value is 25%.
+
+@item passphrase=@var{string}
+HaiCrypt Encryption/Decryption Passphrase string, length
+from 10 to 79 characters. The passphrase is the shared
+secret between the sender and the receiver. It is used
+to generate the Key Encrypting Key using PBKDF2
+(Password-Based Key Deriviation Function). It is used
+only if @option{pbkeylen} is non-zero. It is used on
+the receiver only if the received data is encrypted.
+The configured passphrase cannot be get back (write-only).
+
+@item pbkeylen=@var{bytes}
+Sender encryption key length, in bytes.
+Only can be set to 0, 16, 24 and 32.
+Enable sender encryption if not 0.
+Not required on receiver (set to 0),
+key size obtained from sender in HaiCrypt handshake.
+Default value is 0.
+
+@item recv_buffer_size=@var{bytes}
+Set receive buffer size, expressed bytes.
+
+@item send_buffer_size=@var{bytes}
+Set send buffer size, expressed bytes.
+
+@item rw_timeout
+Set raise error timeout.
+
+This option is only relevant in read mode:
+if no data arrived in more than this time
+interval, raise error.
+
+@item tlpktdrop=@var{1|0}
+Too-late Packet Drop. When enabled on receiver, it skips
+missing packets that have not been delivered in time and
+deliver the following packets to the application when
+their time-to-play has come. It also send a fake ACK to
+sender. When enabled on sender and enabled on the
+receiving peer, sender drops the older packets that
+have no chance to be delivered in time. It was
+automatically enabled in sender if receiver supports it.
+
+@item tsbpddelay
+Timestamp-based Packet Delivery Delay.
+Used to absorb burst of missed packet retransmission.
+
+@end table
+
+For more information see: @url{https://github.com/Haivision/srt}.
+
@section tcp

Transmission Control Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 2c1c0f6d7f..8a3b748cfb 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -398,6 +398,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o
OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_OPENSRT_PROTOCOL) += opensrt.o
OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
diff --git a/libavformat/opensrt.c b/libavformat/opensrt.c
new file mode 100644
index 0000000000..7c738b390e
--- /dev/null
+++ b/libavformat/opensrt.c
@@ -0,0 +1,575 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Haivision Open SRT (Secure Reliable Transport) protocol
+ */
+
+#include "avformat.h"
+#include "libavutil/avassert.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+
+#include "internal.h"
+#include "network.h"
+#include "os_support.h"
+#include "url.h"
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+
+#include <srt/srt.h>
+
+enum SRTMode {
+ SRT_MODE_CALLER = 0,
+ SRT_MODE_LISTENER = 1,
+ SRT_MODE_RENDEZVOUS = 2
+};
+
+typedef struct SRTContext {
+ const AVClass *class;
+ int fd;
+ int eid;
+ int64_t rw_timeout;
+ int64_t listen_timeout;
+ int recv_buffer_size;
+ int send_buffer_size;
+
+ int64_t maxbw;
+ int pbkeylen;
+ char *passphrase;
+ int mss;
+ int fc;
+ int ipttl;
+ int iptos;
+ int64_t inputbw;
+ int oheadbw;
+ int64_t tsbpddelay;
+ int tlpktdrop;
+ int nakreport;
+ int64_t connect_timeout;
+ enum SRTMode mode;
+} SRTContext;
+
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+#define OFFSET(x) offsetof(SRTContext, x)
+static const AVOption opensrt_options[] = {
+ { "rw_timeout", "Timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "listen_timeout", "Connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "recv_buffer_size", "Socket receive buffer size (in bytes)", OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "maxbw", "Maximum bandwidth (bytes per second) that the connection can use", OFFSET(maxbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "pbkeylen", "Crypto key len in bytes {16,24,32} Default: 16 (128-bit)", OFFSET(pbkeylen), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 32, .flags = D|E },
+ { "passphrase", "Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto", OFFSET(passphrase), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
+ { "mss", "The Maximum Segment Size", OFFSET(mss), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1500, .flags = D|E },
+ { "fc", "Flight flag size (window size) (in bytes)", OFFSET(fc), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "ipttl", "IP Time To Live", OFFSET(ipttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
+ { "iptos", "IP Type of Service", OFFSET(iptos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
+ { "inputbw", "Estimated input stream rate", OFFSET(inputbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "oheadbw", "MaxBW ceiling based on % over input stream rate", OFFSET(oheadbw), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, .flags = D|E },
+ { "tsbpddelay", "TsbPd receiver delay to absorb burst of missed packet retransmission", OFFSET(tsbpddelay), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "tlpktdrop", "Enable receiver pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, .flags = D|E },
+ { "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, .flags = D|E },
+ { "connect_timeout", "Connect timeout. Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "mode", "Connection mode (caller, listener, rendezvous)", OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = SRT_MODE_CALLER }, SRT_MODE_CALLER, SRT_MODE_RENDEZVOUS, .flags = D|E, "mode" },
+ { "caller", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_CALLER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
+ { "listener", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_LISTENER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
+ { "rendezvous", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_RENDEZVOUS }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
+ { NULL }
+};
+
+static const AVClass opensrt_class = {
+ .class_name = "opensrt",
+ .item_name = av_default_item_name,
+ .option = opensrt_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+static int opensrt_neterrno(URLContext *h)
+{
+ int err = srt_getlasterror(NULL);
+ av_log(h, AV_LOG_ERROR, "%s\n", srt_getlasterror_str());
+ if (err == SRT_EASYNCRCV)
+ return AVERROR(EAGAIN);
+ return AVERROR_UNKNOWN;
+}
+
+static int opensrt_socket_nonblock(int socket, int enable)
+{
+ int ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &enable, sizeof(enable));
+ if (ret < 0)
+ return ret;
+ ret = srt_setsockopt(socket, 0, SRTO_RCVSYN, &enable, sizeof(enable));
+ return ret;
+}
+
+static int opensrt_network_wait_fd(URLContext *h, int eid, int fd, int write)
+{
+ int ret, len = 1;
+ int modes = write ? SRT_EPOLL_OUT : SRT_EPOLL_IN;
+ SRTSOCKET ready[1];
+
+ if (srt_epoll_add_usock(eid, fd, &modes) < 0)
+ return opensrt_neterrno(h);
+ if (write) {
+ ret = srt_epoll_wait(eid, 0, 0, ready, &len, POLLING_TIME, 0, 0, 0, 0);
+ } else {
+ ret = srt_epoll_wait(eid, ready, &len, 0, 0, POLLING_TIME, 0, 0, 0, 0);
+ }
+ if (ret < 0) {
+ if (srt_getlasterror(NULL) == SRT_ETIMEOUT)
+ ret = AVERROR(EAGAIN);
+ else
+ ret = opensrt_neterrno(h);
+ } else {
+ ret = 0;
+ }
+ if (srt_epoll_remove_usock(eid, fd) < 0)
+ return opensrt_neterrno(h);
+ return ret;
+}
+
+/* TODO de-duplicate code from ff_network_wait_fd_timeout() */
+
+static int opensrt_network_wait_fd_timeout(URLContext *h, int eid, int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
+{
+ int ret;
+ int64_t wait_start = 0;
+
+ while (1) {
+ if (ff_check_interrupt(int_cb))
+ return AVERROR_EXIT;
+ ret = opensrt_network_wait_fd(h, eid, fd, write);
+ if (ret != AVERROR(EAGAIN))
+ return ret;
+ if (timeout > 0) {
+ if (!wait_start)
+ wait_start = av_gettime_relative();
+ else if (av_gettime_relative() - wait_start > timeout)
+ return AVERROR(ETIMEDOUT);
+ }
+ }
+}
+
+static int opensrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int timeout)
+{
+ int ret;
+ int reuse = 1;
+ if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, sizeof(reuse))) {
+ av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_REUSEADDR) failed\n");
+ }
+ ret = srt_bind(fd, addr, addrlen);
+ if (ret)
+ return opensrt_neterrno(h);
+
+ ret = srt_listen(fd, 1);
+ if (ret)
+ return opensrt_neterrno(h);
+
+ while ((ret = opensrt_network_wait_fd_timeout(h, eid, fd, 1, timeout, &h->interrupt_callback))) {
+ switch (ret) {
+ case AVERROR(ETIMEDOUT):
+ continue;
+ default:
+ return ret;
+ }
+ }
+
+ ret = srt_accept(fd, NULL, NULL);
+ if (ret < 0)
+ return opensrt_neterrno(h);
+ if (opensrt_socket_nonblock(ret, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "opensrt_socket_nonblock failed\n");
+
+ return ret;
+}
+
+static int opensrt_listen_connect(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next)
+{
+ int ret;
+
+ if (opensrt_socket_nonblock(fd, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
+
+ while ((ret = srt_connect(fd, addr, addrlen))) {
+ ret = opensrt_neterrno(h);
+ switch (ret) {
+ case AVERROR(EINTR):
+ if (ff_check_interrupt(&h->interrupt_callback))
+ return AVERROR_EXIT;
+ continue;
+ case AVERROR(EINPROGRESS):
+ case AVERROR(EAGAIN):
+ ret = opensrt_network_wait_fd_timeout(h, eid, fd, 1, timeout, &h->interrupt_callback);
+ if (ret < 0)
+ return ret;
+ ret = srt_getlasterror(NULL);
+ srt_clearlasterror();
+ if (ret != 0) {
+ char buf[128];
+ ret = AVERROR(ret);
+ av_strerror(ret, buf, sizeof(buf));
+ if (will_try_next)
+ av_log(h, AV_LOG_WARNING,
+ "Connection to %s failed (%s), trying next address\n",
+ h->filename, buf);
+ else
+ av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
+ h->filename, buf);
+ }
+ default:
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int opensrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, const void * optval, int optlen)
+{
+ if (srt_setsockopt(fd, 0, optname, optval, optlen) < 0) {
+ av_log(h, AV_LOG_ERROR, "failed to set option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+/* - The "POST" options can be altered any time on a connected socket.
+ They MAY have also some meaning when set prior to connecting; such
+ option is SRTO_RCVSYN, which makes connect/accept call asynchronous.
+ Because of that this option is treated special way in this app. */
+static int opensrt_set_options_post(URLContext *h, int fd)
+{
+ SRTContext *s = h->priv_data;
+
+ if (s->inputbw >= 0 && opensrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->oheadbw >= 0 && opensrt_setsockopt(h, fd, SRTO_OHEADBW, "SRTO_OHEADBW", &s->oheadbw, sizeof(s->oheadbw)) < 0) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+/* - The "PRE" options must be set prior to connecting and can't be altered
+ on a connected socket, however if set on a listening socket, they are
+ derived by accept-ed socket. */
+static int opensrt_set_options_pre(URLContext *h, int fd)
+{
+ SRTContext *s = h->priv_data;
+ int yes = 1;
+ int tsbpddelay = s->tsbpddelay / 1000;
+ int connect_timeout = s->connect_timeout;
+
+ if (s->mode == SRT_MODE_RENDEZVOUS && opensrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->maxbw >= 0 && opensrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->pbkeylen >= 0 && opensrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->passphrase && opensrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->mss >= 0 && opensrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->fc >= 0 && opensrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->fc, sizeof(s->fc)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->ipttl >= 0 && opensrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->iptos >= 0 && opensrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (tsbpddelay >= 0 && opensrt_setsockopt(h, fd, SRTO_TSBPDDELAY, "SRTO_TSBPDELAY", &tsbpddelay, sizeof(tsbpddelay)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->tlpktdrop >= 0 && opensrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->nakreport >= 0 && opensrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (connect_timeout >= 0 && opensrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) < 0) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+
+static int opensrt_setup(URLContext *h, const char *uri, int flags)
+{
+ struct addrinfo hints = { 0 }, *ai, *cur_ai;
+ int port, fd = -1;
+ SRTContext *s = h->priv_data;
+ const char *p;
+ char buf[256];
+ int ret;
+ char hostname[1024],proto[1024],path[1024];
+ char portstr[10];
+ int open_timeout = 5000000;
+ int eid;
+
+ eid = srt_epoll_create();
+ if (eid < 0)
+ return opensrt_neterrno(h);
+ s->eid = eid;
+
+ av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
+ &port, path, sizeof(path), uri);
+ if (strcmp(proto, "srt"))
+ return AVERROR(EINVAL);
+ if (port <= 0 || port >= 65536) {
+ av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
+ return AVERROR(EINVAL);
+ }
+ p = strchr(uri, '?');
+ if (p) {
+ if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
+ s->rw_timeout = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
+ s->listen_timeout = strtol(buf, NULL, 10);
+ }
+ }
+ if (s->rw_timeout >= 0) {
+ open_timeout = h->rw_timeout = s->rw_timeout;
+ }
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(portstr, sizeof(portstr), "%d", port);
+ if (s->mode == SRT_MODE_LISTENER)
+ hints.ai_flags |= AI_PASSIVE;
+ ret = getaddrinfo(hostname[0] ? hostname : NULL, portstr, &hints, &ai);
+ if (ret) {
+ av_log(h, AV_LOG_ERROR,
+ "Failed to resolve hostname %s: %s\n",
+ hostname, gai_strerror(ret));
+ return AVERROR(EIO);
+ }
+
+ cur_ai = ai;
+
+ restart:
+
+ fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
+ if (fd < 0) {
+ ret = opensrt_neterrno(h);
+ goto fail;
+ }
+
+ if ((ret = opensrt_set_options_pre(h, fd)) < 0) {
+ goto fail;
+ }
+
+ /* Set the socket's send or receive buffer sizes, if specified.
+ If unspecified or setting fails, system default is used. */
+ if (s->recv_buffer_size > 0) {
+ srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size));
+ }
+ if (s->send_buffer_size > 0) {
+ srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size));
+ }
+ if (s->mode == SRT_MODE_LISTENER) {
+ // multi-client
+ if ((ret = opensrt_listen(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, open_timeout / 1000)) < 0)
+ goto fail1;
+ fd = ret;
+ } else {
+ if (s->mode == SRT_MODE_RENDEZVOUS) {
+ ret = srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+ if (ret)
+ goto fail1;
+ }
+
+ if ((ret = opensrt_listen_connect(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+ open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) {
+ if (ret == AVERROR_EXIT)
+ goto fail1;
+ else
+ goto fail;
+ }
+ }
+ if ((ret = opensrt_set_options_post(h, fd)) < 0) {
+ goto fail;
+ }
+
+ h->is_streamed = 1;
+ s->fd = fd;
+
+ freeaddrinfo(ai);
+ return 0;
+
+ fail:
+ if (cur_ai->ai_next) {
+ /* Retry with the next sockaddr */
+ cur_ai = cur_ai->ai_next;
+ if (fd >= 0)
+ srt_close(fd);
+ ret = 0;
+ goto restart;
+ }
+ fail1:
+ if (fd >= 0)
+ srt_close(fd);
+ freeaddrinfo(ai);
+ return ret;
+}
+
+static int opensrt_open(URLContext *h, const char *uri, int flags)
+{
+ SRTContext *s = h->priv_data;
+ const char * p;
+ char buf[256];
+
+ if (srt_startup() < 0) {
+ return AVERROR_UNKNOWN;
+ }
+
+ /* SRT options (srt/srt.h) */
+ p = strchr(uri, '?');
+ if (p)
+ {
+ if (av_find_info_tag(buf, sizeof(buf), "maxbw", p)) {
+ s->maxbw = strtoll(buf, NULL, 0);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "pbkeylen", p)) {
+ s->pbkeylen = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "passphrase", p)) {
+ s->passphrase = av_strndup(buf, strlen(buf));
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "mss", p)) {
+ s->mss = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "fc", p)) {
+ s->fc = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "ipttl", p)) {
+ s->ipttl = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "iptos", p)) {
+ s->iptos = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "inputbw", p)) {
+ s->inputbw = strtoll(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "oheadbw", p)) {
+ s->oheadbw = strtoll(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "tsbpddelay", p)) {
+ s->tsbpddelay = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "tlpktdrop", p)) {
+ s->tlpktdrop = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "nakreport", p)) {
+ s->nakreport = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "connect_timeout", p)) {
+ s->connect_timeout = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "mode", p)) {
+ if (!strcmp(buf, "caller")) {
+ s->mode = SRT_MODE_CALLER;
+ } else if (!strcmp(buf, "listener")) {
+ s->mode = SRT_MODE_LISTENER;
+ } else if (!strcmp(buf, "rendezvous")) {
+ s->mode = SRT_MODE_RENDEZVOUS;
+ } else {
+ return AVERROR(EIO);
+ }
+ }
+ }
+ return opensrt_setup(h, uri, flags);
+}
+
+static int opensrt_read(URLContext *h, uint8_t *buf, int size)
+{
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = opensrt_network_wait_fd_timeout(h, s->eid, s->fd, 0, h->rw_timeout, &h->interrupt_callback);
+ if (ret)
+ return ret;
+ }
+
+ ret = srt_recvmsg(s->fd, buf, size);
+ if (ret < 0) {
+ ret = opensrt_neterrno(h);
+ }
+
+ return ret;
+}
+
+static int opensrt_write(URLContext *h, const uint8_t *buf, int size)
+{
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = opensrt_network_wait_fd_timeout(h, s->eid, s->fd, 1, h->rw_timeout, &h->interrupt_callback);
+ if (ret)
+ return ret;
+ }
+
+ ret = srt_sendmsg(s->fd, buf, size, -1, 0);
+ if (ret < 0) {
+ ret = opensrt_neterrno(h);
+ }
+
+ return ret;
+}
+
+static int opensrt_close(URLContext *h)
+{
+ SRTContext *s = h->priv_data;
+
+ srt_close(s->fd);
+
+ srt_epoll_release(s->eid);
+
+ srt_cleanup();
+
+ return 0;
+}
+
+static int opensrt_get_file_handle(URLContext *h)
+{
+ SRTContext *s = h->priv_data;
+ return s->fd;
+}
+
+const URLProtocol ff_opensrt_protocol = {
+ .name = "srt",
+ .url_open = opensrt_open,
+ .url_read = opensrt_read,
+ .url_write = opensrt_write,
+ .url_close = opensrt_close,
+ .url_get_file_handle = opensrt_get_file_handle,
+ .priv_data_size = sizeof(SRTContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &opensrt_class,
+};
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 8ea5c0e757..c2ae72d20b 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -38,6 +38,7 @@ extern const URLProtocol ff_mmsh_protocol;
extern const URLProtocol ff_mmst_protocol;
extern const URLProtocol ff_md5_protocol;
extern const URLProtocol ff_pipe_protocol;
+extern const URLProtocol ff_opensrt_protocol;
extern const URLProtocol ff_rtmp_protocol;
extern const URLProtocol ff_rtmpe_protocol;
extern const URLProtocol ff_rtmps_protocol;
--
2.12.2
Diego Biurrun
2018-03-21 10:46:52 UTC
Permalink
Post by Luca Barbato
protocol requires libsrt (https://github.com/Haivision/srt) to be
installed
---
Here the patch with all the changes folded in, I'll push it tonight if
nobody has further comments.
Did the new formats checklist get out of fashion lately?

https://www.libav.org/documentation/developer.html#New-codecs-or-formats-checklist
Post by Luca Barbato
--- a/configure
+++ b/configure
@@ -1371,6 +1372,7 @@ EXTERNAL_LIBRARY_LIST="
libspeex
+ libsrt
libtheora
@@ -2522,6 +2524,8 @@ librtmpt_protocol_deps="librtmp"
mmst_protocol_select="network"
+opensrt_protocol_select="network"
+opensrt_protocol_deps="libsrt"
rtmp_protocol_conflict="librtmp_protocol"
What is it? libsrt or opensrt?
Post by Luca Barbato
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -655,6 +655,145 @@ To play back the first stream announced on one the default IPv6 SAP multicast ad
avplay sap://[ff0e::2:7ffe]
@end example
+
+Haivision Secure Reliable Transport Protocol via libsrt.
+
URL
Post by Luca Barbato
+
Do you have to escape '&'? I don't remember offhand.
Post by Luca Barbato
+
+or
+
+
+options.
+
+This protocol accepts the following options.
+
+Connection timeout. SRT cannot connect for RTT > 1500 msec
Connection timeout;
Post by Luca Barbato
+Flight Flag Size (Window Size), in bytes. FC is actually an
ffs? loool ;)
Post by Luca Barbato
+internal parameter and you should set it to not less than
+is relatively large, therefore unless you set a very large receiver buffer,
+you do not need to change this option. Default value is 25600.
This sounds like it should not be a user-tunable parameter, but that
the implementation should take care of it instead. Oh well ..
Post by Luca Barbato
+Sender nominal input rate, in bytes per seconds. Used along with
+calculate maximum sending rate when recovery packets are sent
with the
Post by Luca Barbato
+relative (0), the actual ctual input rate is evaluated inside
ctual?
Post by Luca Barbato
+Maximum sending bandwidth, in bytes per seconds.
+-1 infinite (CSRTCC limit is 30mbps)
+>0 absolute limit value
+Default value is 0 (relative)
+
+Connection mode.
+caller opens client connection.
+listener starts server to listen for incoming connections.
+rendezvous use Rendez-Vous connection mode.
+Default valus is caller.
s/valus/value/
Post by Luca Barbato
+Maximum Segment Size, in bytes. Used for buffer allocation
+and rate calculation using packet counter assuming fully
a packet counter
Post by Luca Barbato
+filled packets. The smallest MSS between the peers is
+used. This is 1500 by default in the overall internet.
+This is the maximum size of the UDP packet and can be
+only decreased, unless you have some unusual dedicated
+network settings. Default value is 1500.
+
+If set to 1, Receiver will send `UMSG_LOSSREPORT` messages
+periodically until the lost packet is retransmitted or
s/the/a/ I assume
Post by Luca Barbato
+
+Recovery bandwidth overhead above input rate, in percents.
+
+HaiCrypt Encryption/Decryption Passphrase string, length
+from 10 to 79 characters. The passphrase is the shared
+secret between the sender and the receiver. It is used
+to generate the Key Encrypting Key using PBKDF2
+(Password-Based Key Deriviation Function). It is used
Deriv_ation
Post by Luca Barbato
+the receiver only if the received data is encrypted.
+The configured passphrase cannot be get back (write-only).
s/get back/recovered/
Post by Luca Barbato
+Set receive buffer size, expressed bytes.
+
+Set send buffer size, expressed bytes.
expressed in
Post by Luca Barbato
+Set raise error timeout.
rw?
Post by Luca Barbato
+if no data arrived in more than this time
+interval, raise error.
+
+Too-late Packet Drop. When enabled on receiver, it skips
+missing packets that have not been delivered in time and
+deliver the following packets to the application when
deliverS
Post by Luca Barbato
+their time-to-play has come. It also send a fake ACK to
sendS
Post by Luca Barbato
+sender. When enabled on sender and enabled on the
the sender
Post by Luca Barbato
+receiving peer, sender drops the older packets that
the sender
Post by Luca Barbato
+have no chance to be delivered in time. It was
of being delivered
Post by Luca Barbato
+automatically enabled in sender if receiver supports it.
the sender, the receiver
Post by Luca Barbato
+Timestamp-based Packet Delivery Delay.
+Used to absorb burst of missed packet retransmission.
I'm generally sceptical of all those options, are they really necessary?
Also, the names look like line noise.
Post by Luca Barbato
--- /dev/null
+++ b/libavformat/opensrt.c
@@ -0,0 +1,575 @@
+
+#include "avformat.h"
+#include "libavutil/avassert.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+
+#include "internal.h"
+#include "network.h"
+#include "os_support.h"
+#include "url.h"
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+
+#include <srt/srt.h>
nit: canonical order
Post by Luca Barbato
+static const AVClass opensrt_class = {
+ .class_name = "opensrt",
+ .item_name = av_default_item_name,
+ .option = opensrt_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
This would make more sense close to where it is used.
Post by Luca Barbato
+static int opensrt_socket_nonblock(int socket, int enable)
+{
+ int ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &enable, sizeof(enable));
+ if (ret < 0)
+ return ret;
+ ret = srt_setsockopt(socket, 0, SRTO_RCVSYN, &enable, sizeof(enable));
+ return ret;
nit: return directly
Post by Luca Barbato
+static int opensrt_set_options_post(URLContext *h, int fd)
+{
+ if (s->inputbw >= 0 && opensrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->oheadbw >= 0 && opensrt_setsockopt(h, fd, SRTO_OHEADBW, "SRTO_OHEADBW", &s->oheadbw, sizeof(s->oheadbw)) < 0) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+static int opensrt_set_options_pre(URLContext *h, int fd)
+{
+ if (s->mode == SRT_MODE_RENDEZVOUS && opensrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->maxbw >= 0 && opensrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->pbkeylen >= 0 && opensrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->passphrase && opensrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->mss >= 0 && opensrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->fc >= 0 && opensrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->fc, sizeof(s->fc)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->ipttl >= 0 && opensrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->iptos >= 0 && opensrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (tsbpddelay >= 0 && opensrt_setsockopt(h, fd, SRTO_TSBPDDELAY, "SRTO_TSBPDELAY", &tsbpddelay, sizeof(tsbpddelay)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->tlpktdrop >= 0 && opensrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (s->nakreport >= 0 && opensrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) {
+ return AVERROR(EIO);
+ }
+ if (connect_timeout >= 0 && opensrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) < 0) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
Connecting all these through || would be more readable.
Post by Luca Barbato
+static int opensrt_open(URLContext *h, const char *uri, int flags)
+ p = strchr(uri, '?');
+ if (p)
+ {
style
Post by Luca Barbato
+const URLProtocol ff_opensrt_protocol = {
+ .name = "srt",
+ .url_open = opensrt_open,
+ .url_read = opensrt_read,
+ .url_write = opensrt_write,
+ .url_close = opensrt_close,
+ .url_get_file_handle = opensrt_get_file_handle,
+ .priv_data_size = sizeof(SRTContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &opensrt_class,
+};
The names mismatch between srt, opensrt, and libsrt.

Where does the opensrt name come from?
Post by Luca Barbato
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -38,6 +38,7 @@ extern const URLProtocol ff_mmsh_protocol;
extern const URLProtocol ff_mmst_protocol;
extern const URLProtocol ff_md5_protocol;
extern const URLProtocol ff_pipe_protocol;
+extern const URLProtocol ff_opensrt_protocol;
extern const URLProtocol ff_rtmp_protocol;
extern const URLProtocol ff_rtmpe_protocol;
extern const URLProtocol ff_rtmps_protocol;
order

Diego
Luca Barbato
2018-03-21 14:00:37 UTC
Permalink
Post by Diego Biurrun
Post by Luca Barbato
protocol requires libsrt (https://github.com/Haivision/srt) to be
installed
---
Here the patch with all the changes folded in, I'll push it tonight if
nobody has further comments.
Did the new formats checklist get out of fashion lately?
https://www.libav.org/documentation/developer.html#New-codecs-or-formats-checklist
It isn't a format or a codec.
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.

I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Do you have to escape '&'? I don't remember offhand.
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for it uses
an external opensource implementation, as mentioned in many places.

I edited opensrt to libsrt for the configuration option since it fits
the normal pattern better. Probably to be consistent renaming all the
other occurrences of opensrt to libsrt would be an option.

Sven what sounds better for you?

lu
Diego Biurrun
2018-03-21 14:53:57 UTC
Permalink
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for it uses an
external opensource implementation, as mentioned in many places.
I edited opensrt to libsrt for the configuration option since it fits the
normal pattern better. Probably to be consistent renaming all the other
occurrences of opensrt to libsrt would be an option.
I don't see the opensrt name appearing anywhere. Plain srt should be the
name for an internal implementation, for external-library-backed ones a
lib prefix to the name of the protocol is appropriate.

Diego
Sven Dueking
2018-03-21 15:03:18 UTC
Permalink
-----Ursprüngliche Nachricht-----
Diego Biurrun
Gesendet: Mittwoch, 21. März 2018 15:54
An: libav development
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for it
uses an external opensource implementation, as mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it fits
the normal pattern better. Probably to be consistent renaming all the
other occurrences of opensrt to libsrt would be an option.
I don't see the opensrt name appearing anywhere. Plain srt should be
the name for an internal implementation, for external-library-backed
ones a lib prefix to the name of the protocol is appropriate.
Diego
Haivison calls the packet OpenSRT and I think that´s a good idea to avoid any conflicts with SRT (subtitle).
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
Luca Barbato
2018-03-22 09:41:15 UTC
Permalink
Post by Sven Dueking
-----Ursprüngliche Nachricht-----
Diego Biurrun
Gesendet: Mittwoch, 21. März 2018 15:54
An: libav development
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for it
uses an external opensource implementation, as mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it fits
the normal pattern better. Probably to be consistent renaming all the
other occurrences of opensrt to libsrt would be an option.
I don't see the opensrt name appearing anywhere. Plain srt should be
the name for an internal implementation, for external-library-backed
ones a lib prefix to the name of the protocol is appropriate.
Diego
Haivison calls the packet OpenSRT and I think that´s a good idea to avoid any conflicts with SRT (subtitle).
Then OpenSRT/opensrt is good for me as well.

lu
Diego Biurrun
2018-03-22 11:23:53 UTC
Permalink
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for it
uses an external opensource implementation, as mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it fits
the normal pattern better. Probably to be consistent renaming all the
other occurrences of opensrt to libsrt would be an option.
I don't see the opensrt name appearing anywhere. Plain srt should be
the name for an internal implementation, for external-library-backed
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good idea to
avoid any conflicts with SRT (subtitle).
Umm, no?

***@libav-fate:/tmp$ git clone git://github.com/Haivision/srt
Cloning into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused 1523
Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (1042/1042), done.
***@libav-fate:/tmp$ cd srt/
***@libav-fate:/tmp/srt$ git grep -i "opensrt"
***@libav-fate:/tmp/srt$ git grep -i "open srt"
***@libav-fate:/tmp/srt$

The library calls itself libsrt, the namespace prefix for API functions
it uses is "srt_". Following that naming scheme on our side makes sense,
let's just drop the "open" from file names, protocol names, and function
names. We do that for all other, similar, external libraries.

Diego
Sven Dueking
2018-03-22 11:34:29 UTC
Permalink
-----Ursprüngliche Nachricht-----
Diego Biurrun
Gesendet: Donnerstag, 22. März 2018 12:24
An: libav development
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for
it uses an external opensource implementation, as mentioned in
many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it
fits the normal pattern better. Probably to be consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-library-
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good idea to
avoid any conflicts with SRT (subtitle).
Umm, no?
into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused 1523
Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API functions
it uses is "srt_". Following that naming scheme on our side makes
sense, let's just drop the "open" from file names, protocol names, and
function names. We do that for all other, similar, external libraries.
Diego
We will change the name back to opensrt in all places.
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
Diego Biurrun
2018-03-22 12:17:16 UTC
Permalink
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for
it uses an external opensource implementation, as mentioned in
many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it
fits the normal pattern better. Probably to be consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-library-
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good idea to
avoid any conflicts with SRT (subtitle).
Umm, no?
into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused 1523
Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API functions
it uses is "srt_". Following that naming scheme on our side makes
sense, let's just drop the "open" from file names, protocol names, and
function names. We do that for all other, similar, external libraries.
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we should
wait with this wrapper until that change in libsrt is done.

Notice that protocols and (subtitle) demuxers live in different namespaces.
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.

Diego
wm4
2018-03-22 13:03:03 UTC
Permalink
On Thu, 22 Mar 2018 13:17:16 +0100
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for
it uses an external opensource implementation, as mentioned in
many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it
fits the normal pattern better. Probably to be consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-library-
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good idea to
avoid any conflicts with SRT (subtitle).
Umm, no?
into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused 1523
Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API functions
it uses is "srt_". Following that naming scheme on our side makes
sense, let's just drop the "open" from file names, protocol names, and
function names. We do that for all other, similar, external libraries.
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we should
wait with this wrapper until that change in libsrt is done.
Notice that protocols and (subtitle) demuxers live in different namespaces.
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Diego Biurrun
2018-03-22 13:24:01 UTC
Permalink
Post by wm4
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for
it uses an external opensource implementation, as mentioned in
many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it
fits the normal pattern better. Probably to be consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-library-
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good idea to
avoid any conflicts with SRT (subtitle).
Umm, no?
into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused 1523
Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API functions
it uses is "srt_". Following that naming scheme on our side makes
sense, let's just drop the "open" from file names, protocol names, and
function names. We do that for all other, similar, external libraries.
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we should
wait with this wrapper until that change in libsrt is done.
Notice that protocols and (subtitle) demuxers live in different namespaces.
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Do you see an alternative? It's not like I came up with the (sort of)
duplicate name myself..

Diego
Sven Dueking
2018-03-22 13:24:08 UTC
Permalink
-----Ursprüngliche Nachricht-----
wm4
Gesendet: Donnerstag, 22. März 2018 14:03
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
On Thu, 22 Mar 2018 13:17:16 +0100
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the
support
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
for it uses an external opensource implementation, as
mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option
since it fits the normal pattern better. Probably to be
consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-
library-
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good
idea
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
to avoid any conflicts with SRT (subtitle).
Umm, no?
Cloning into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused
1523 Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s,
done.
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API
functions it uses is "srt_". Following that naming scheme on our
side makes sense, let's just drop the "open" from file names,
protocol names, and function names. We do that for all other,
similar, external libraries.
Post by Diego Biurrun
Post by Sven Dueking
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we
should wait with this wrapper until that change in libsrt is done.
Notice that protocols and (subtitle) demuxers live in different
namespaces.
Post by Diego Biurrun
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Any idea for a better name or shell we discuss this for the next days ?
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
wm4
2018-03-22 13:37:40 UTC
Permalink
On Thu, 22 Mar 2018 14:24:08 +0100
Post by Sven Dueking
-----Ursprüngliche Nachricht-----
wm4
Gesendet: Donnerstag, 22. März 2018 14:03
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
On Thu, 22 Mar 2018 13:17:16 +0100
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the
support
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
for it uses an external opensource implementation, as
mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option
since it fits the normal pattern better. Probably to be
consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-
library-
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good
idea
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
to avoid any conflicts with SRT (subtitle).
Umm, no?
Cloning into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused
1523 Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s,
done.
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API
functions it uses is "srt_". Following that naming scheme on our
side makes sense, let's just drop the "open" from file names,
protocol names, and function names. We do that for all other,
similar, external libraries.
Post by Diego Biurrun
Post by Sven Dueking
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we
should wait with this wrapper until that change in libsrt is done.
Notice that protocols and (subtitle) demuxers live in different
namespaces.
Post by Diego Biurrun
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Any idea for a better name or shell we discuss this for the next days ?
There's a lot of names you could come up with. Personally I think that
something like "hosrt" or "haisrt" would already sound very different
from the SRT subtitle format or RTP variants, so that no confusion can
happen.
Sven Dueking
2018-03-22 13:42:40 UTC
Permalink
-----Ursprüngliche Nachricht-----
wm4
Gesendet: Donnerstag, 22. März 2018 14:38
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
On Thu, 22 Mar 2018 14:24:08 +0100
Post by Sven Dueking
-----Ursprüngliche Nachricht-----
wm4
Gesendet: Donnerstag, 22. März 2018 14:03
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
On Thu, 22 Mar 2018 13:17:16 +0100
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
On Wed, Mar 21, 2018 at 03:00:37PM +0100, Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol
SRT.
Post by Sven Dueking
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the
support
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
for it uses an external opensource implementation, as
mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option
since it fits the normal pattern better. Probably to be
consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
I don't see the opensrt name appearing anywhere. Plain
srt
Post by Sven Dueking
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
should
be
Post by Sven Dueking
the name for an internal implementation, for external-
library-
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
backed
Post by Sven Dueking
ones a lib prefix to the name of the protocol is
appropriate.
Post by Sven Dueking
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Haivison calls the packet OpenSRT and I think that´s a good
idea
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
to avoid any conflicts with SRT (subtitle).
Umm, no?
git://github.com/Haivision/srt Cloning into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8),
pack-reused
1523 Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s,
done.
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Resolving deltas: 100% (1042/1042), done.
grep -i "opensrt"
The library calls itself libsrt, the namespace prefix for API
functions it uses is "srt_". Following that naming scheme on
our side makes sense, let's just drop the "open" from file
names, protocol names, and function names. We do that for all
other,
similar, external libraries.
Post by Diego Biurrun
Post by Sven Dueking
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we
should wait with this wrapper until that change in libsrt is
done.
Post by Sven Dueking
Post by Diego Biurrun
Notice that protocols and (subtitle) demuxers live in different
namespaces.
Post by Diego Biurrun
There is no conflict between an "srt" protocol (should be
"libsrt"
Post by Sven Dueking
Post by Diego Biurrun
in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Any idea for a better name or shell we discuss this for the next days
?
There's a lot of names you could come up with. Personally I think that
something like "hosrt" or "haisrt" would already sound very different
from the SRT subtitle format or RTP variants, so that no confusion can
happen.
Thanks much for your personal, but I disagree and still think opensrt is fine. I really see no reason why this should confuse users and any relation to RTP. Besides this, I send this patch to FFMPEG month ago and you didn´t response about the name. Looking for forward to get more feedback from the community about the name of this lib, since it seems to be very important.
_______________________________________________
libav-devel mailing list
https://lists.libav.org/mailman/listinfo/libav-devel
wm4
2018-03-22 13:55:16 UTC
Permalink
On Thu, 22 Mar 2018 14:42:40 +0100
Post by Sven Dueking
-----Ursprüngliche Nachricht-----
wm4
Gesendet: Donnerstag, 22. März 2018 14:38
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
On Thu, 22 Mar 2018 14:24:08 +0100
Post by Sven Dueking
-----Ursprüngliche Nachricht-----
wm4
Gesendet: Donnerstag, 22. März 2018 14:03
Betreff: Re: [libav-devel] [PATCH] Add Haivision Open SRT protocol
On Thu, 22 Mar 2018 13:17:16 +0100
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
On Wed, Mar 21, 2018 at 03:00:37PM +0100, Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol
SRT.
Post by Sven Dueking
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the
support
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
for it uses an external opensource implementation, as
mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option
since it fits the normal pattern better. Probably to be
consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be
an
option.
Post by Sven Dueking
I don't see the opensrt name appearing anywhere. Plain
srt
Post by Sven Dueking
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
should
be
Post by Sven Dueking
the name for an internal implementation, for external-
library-
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
backed
Post by Sven Dueking
ones a lib prefix to the name of the protocol is
appropriate.
Post by Sven Dueking
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Haivison calls the packet OpenSRT and I think that´s a good
idea
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
to avoid any conflicts with SRT (subtitle).
Umm, no?
git://github.com/Haivision/srt Cloning into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused
1523 Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s,
done.
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Resolving deltas: 100% (1042/1042), done.
grep -i "opensrt"
The library calls itself libsrt, the namespace prefix for API
functions it uses is "srt_". Following that naming scheme on
our side makes sense, let's just drop the "open" from file
names, protocol names, and function names. We do that for all
other,
similar, external libraries.
Post by Diego Biurrun
Post by Sven Dueking
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we
should wait with this wrapper until that change in libsrt is
done.
Post by Sven Dueking
Post by Diego Biurrun
Notice that protocols and (subtitle) demuxers live in different
namespaces.
Post by Diego Biurrun
There is no conflict between an "srt" protocol (should be
"libsrt"
Post by Sven Dueking
Post by Diego Biurrun
in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Any idea for a better name or shell we discuss this for the next days
?
There's a lot of names you could come up with. Personally I think that
something like "hosrt" or "haisrt" would already sound very different
from the SRT subtitle format or RTP variants, so that no confusion can
happen.
Thanks much for your personal, but I disagree and still think opensrt is fine. I really see no reason why this should confuse users and any relation to RTP. Besides this, I send this patch to FFMPEG month ago and you didn´t response about the name. Looking for forward to get more feedback from the community about the name of this lib, since it seems to be very important.
Well, it was always confusing. At first I thought it was a patch for
some modification of the SRT format, and wondered why that would need
an external library.
Diego Biurrun
2018-03-22 13:51:38 UTC
Permalink
Post by Sven Dueking
Post by Luca Barbato
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the
support
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
for it uses an external opensource implementation, as
mentioned in many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option
since it fits the normal pattern better. Probably to be
consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-
library-
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good
idea
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
to avoid any conflicts with SRT (subtitle).
Umm, no?
Cloning into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused
1523 Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s,
done.
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API
functions it uses is "srt_". Following that naming scheme on our
side makes sense, let's just drop the "open" from file names,
protocol names, and function names. We do that for all other,
similar, external libraries.
Post by Diego Biurrun
Post by Sven Dueking
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we
should wait with this wrapper until that change in libsrt is done.
Notice that protocols and (subtitle) demuxers live in different
namespaces.
Post by Diego Biurrun
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Any idea for a better name or shell we discuss this for the next days ?
Let me first state what the general naming scheme is: external wrappers
for "foo" get a "lib" prefix to "foo", e.g.:

gsmdec.c:
AVCodec ff_gsm_decoder = {
.name = "gsm",

libgsmdec.c:
AVCodec ff_libgsm_decoder = {
.name = "libgsm",

So here it should be libsrt.c and ff_libsrt_protocol and .name="libsrt".
Is there a problem with that naming scheme?


To clarify another question I have: Do you work on the Haivision SRT
implementation?

Diego
Diego Biurrun
2018-03-22 13:54:23 UTC
Permalink
Post by wm4
On Thu, 22 Mar 2018 13:17:16 +0100
Post by Diego Biurrun
Post by Sven Dueking
Post by Luca Barbato
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
Post by Diego Biurrun
What is it? libsrt or opensrt?
You have an opensource implementation of the protocol SRT.
I prefer to call it libsrt as configure option.
Post by Diego Biurrun
Where does the opensrt name come from?
The protocol is srt (secure reliable transport), the support for
it uses an external opensource implementation, as mentioned in
many
places.
Post by Luca Barbato
I edited opensrt to libsrt for the configuration option since it
fits the normal pattern better. Probably to be consistent
renaming
Post by Sven Dueking
Post by Luca Barbato
Post by Luca Barbato
all the other occurrences of opensrt to libsrt would be an
option.
Post by Sven Dueking
Post by Luca Barbato
I don't see the opensrt name appearing anywhere. Plain srt should
be
Post by Sven Dueking
Post by Luca Barbato
the name for an internal implementation, for external-library-
backed
Post by Sven Dueking
Post by Luca Barbato
ones a lib prefix to the name of the protocol is appropriate.
Haivison calls the packet OpenSRT and I think that´s a good idea to
avoid any conflicts with SRT (subtitle).
Umm, no?
into 'srt'...
remote: Counting objects: 1565, done.
remote: Compressing objects: 100% (34/34), done.
remote: Total 1565 (delta 15), reused 16 (delta 8), pack-reused 1523
Receiving objects: 100% (1565/1565), 1.80 MiB | 1.44 MiB/s, done.
Resolving deltas: 100% (1042/1042), done.
The library calls itself libsrt, the namespace prefix for API functions
it uses is "srt_". Following that naming scheme on our side makes
sense, let's just drop the "open" from file names, protocol names, and
function names. We do that for all other, similar, external libraries.
We will change the name back to opensrt in all places.
Thus completely breaking backwards compatibility and API? Then we should
wait with this wrapper until that change in libsrt is done.
Notice that protocols and (subtitle) demuxers live in different namespaces.
There is no conflict between an "srt" protocol (should be "libsrt" in this
case) and an "srt" demuxer.
But it's hellish confusing. Even opensrt is confusing, though.
Where exactly is the confusion? The file name(s)? Getting similar hits
when doing git-grep? Some other thing?

Diego
Sven Dueking
2018-03-26 15:37:49 UTC
Permalink
protocol requires libsrt (https://github.com/Haivision/srt) to be
installed

Signed-off-by: Sven Dueking <***@nablet.com>
Signed-off-by: Luca Barbato <***@gentoo.org>
---
configure | 5 +
doc/protocols.texi | 140 ++++++++++++
libavformat/Makefile | 1 +
libavformat/opensrt.c | 549 ++++++++++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
5 files changed, 696 insertions(+)
create mode 100644 libavformat/opensrt.c

diff --git a/configure b/configure
index 95e6006..adb0341 100755
--- a/configure
+++ b/configure
@@ -229,6 +229,7 @@ External library support:
--enable-libxcb-xfixes X11 mouse rendering [auto]
--enable-libxvid MPEG-4 ASP video encoding
--enable-openssl crypto
+ --enable-opensrt enable Haivision Open SRT protocol [no]
--enable-zlib compression [autodetect]

The following libraries provide various hardware acceleration features:
@@ -1380,6 +1381,7 @@ EXTERNAL_LIBRARY_LIST="
libxcb
libxcb_shm
libxcb_xfixes
+ opensrt
"

SYSTEM_LIBRARY_LIST="
@@ -2522,6 +2524,8 @@ librtmpt_protocol_deps="librtmp"
librtmpte_protocol_deps="librtmp"
mmsh_protocol_select="http_protocol"
mmst_protocol_select="network"
+opensrt_protocol_select="network"
+opensrt_protocol_deps="opensrt"
rtmp_protocol_conflict="librtmp_protocol"
rtmp_protocol_select="tcp_protocol"
rtmp_protocol_suggest="zlib"
@@ -4710,6 +4714,7 @@ enabled omx && require_header OMX_Core.h
enabled omx_rpi && { check_header OMX_Core.h ||
{ ! enabled cross_compile && add_cflags -isystem/opt/vc/include/IL && check_header OMX_Core.h ; } ||
die "ERROR: OpenMAX IL headers not found"; } && enable omx
+enabled opensrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
enabled openssl && { { check_pkg_config openssl openssl openssl/ssl.h OPENSSL_init_ssl ||
check_pkg_config openssl openssl openssl/ssl.h SSL_library_init; } ||
check_lib openssl openssl/ssl.h SSL_library_init -lssl -lcrypto ||
diff --git a/doc/protocols.texi b/doc/protocols.texi
index c136c74..40c755d 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -655,6 +655,146 @@ To play back the first stream announced on one the default IPv6 SAP multicast ad
avplay sap://[ff0e::2:7ffe]
@end example

+@section srt
+
+Haivision Secure Reliable Transport Protocol via libsrt.
+
+The supported syntax for a SRT URL is:
+@example
+srt://@var{hostname}:@var{port}[?@var{options}]
+@end example
+
+@var{options} contains a list of &-separated options of the form
+@var{key}=@var{val}.
+
+or
+
+@example
+@var{options} srt://@var{hostname}:@var{port}
+@end example
+
+@var{options} contains a list of '-@var{key} @var{val}'
+options.
+
+This protocol accepts the following options.
+
+@table @option
+@item connect_timeout
+Connection timeout; SRT cannot connect for RTT > 1500 msec
+(2 handshake exchanges) with the default connect timeout of
+3 seconds. This option applies to the caller and rendezvous
+connection modes. The connect timeout is 10 times the value
+set for the rendezvous mode (which can be used as a
+workaround for this connection problem with earlier versions).
+
+@item ffs=@var{bytes}
+Flight Flag Size (Window Size), in bytes. FFS is actually an
+internal parameter and you should set it to not less than
+@option{recv_buffer_size} and @option{mss}. The default value
+is relatively large, therefore unless you set a very large receiver buffer,
+you do not need to change this option. Default value is 25600.
+
+@item inputbw=@var{bytes/seconds}
+Sender nominal input rate, in bytes per seconds. Used along with
+@option{oheadbw}, when @option{maxbw} is set to relative (0), to
+calculate maximum sending rate when recovery packets are sent
+along with the main media stream:
+@option{inputbw} * (100 + @option{oheadbw}) / 100
+if @option{inputbw} is not set while @option{maxbw} is set to
+relative (0), the actual actual input rate is evaluated inside
+the library. Default value is 0.
+
+@item iptos=@var{tos}
+IP Type of Service. Applies to sender only. Default value is 0xB8.
+
+@item ipttl=@var{ttl}
+IP Time To Live. Applies to sender only. Default value is 64.
+
+@item listen_timeout
+Set socket listen timeout.
+
+@item maxbw=@var{bytes/seconds}
+Maximum sending bandwidth, in bytes per seconds.
+-1 infinite (CSRTCC limit is 30mbps)
+0 relative to input rate (see @option{inputbw})
+>0 absolute limit value
+Default value is 0 (relative)
+
+@item mode=@var{caller|listener|rendezvous}
+Connection mode.
+@option{caller} opens client connection.
+@option{listener} starts server to listen for incoming connections.
+@option{rendezvous} use Rendez-Vous connection mode.
+Default value is caller.
+
+@item mss=@var{bytes}
+Maximum Segment Size, in bytes. Used for buffer allocation
+and rate calculation using a packet counter assuming fully
+filled packets. The smallest MSS between the peers is
+used. This is 1500 by default in the overall internet.
+This is the maximum size of the UDP packet and can be
+only decreased, unless you have some unusual dedicated
+network settings. Default value is 1500.
+
+@item nakreport=@var{1|0}
+If set to 1, Receiver will send `UMSG_LOSSREPORT` messages
+periodically until a lost packet is retransmitted or
+intentionally dropped. Default value is 1.
+
+@item oheadbw=@var{percents}
+Recovery bandwidth overhead above input rate, in percents.
+See @option{inputbw}. Default value is 25%.
+
+@item passphrase=@var{string}
+HaiCrypt Encryption/Decryption Passphrase string, length
+from 10 to 79 characters. The passphrase is the shared
+secret between the sender and the receiver. It is used
+to generate the Key Encrypting Key using PBKDF2
+(Password-Based Key Derivation Function). It is used
+only if @option{pbkeylen} is non-zero. It is used on
+the receiver only if the received data is encrypted.
+The configured passphrase cannot be recovered (write-only).
+
+@item pbkeylen=@var{bytes}
+Sender encryption key length, in bytes.
+Only can be set to 0, 16, 24 and 32.
+Enable sender encryption if not 0.
+Not required on receiver (set to 0),
+key size obtained from sender in HaiCrypt handshake.
+Default value is 0.
+
+@item recv_buffer_size=@var{bytes}
+Set receive buffer size, expressed in bytes.
+
+@item send_buffer_size=@var{bytes}
+Set send buffer size, expressed in bytes.
+
+@item rw_timeout
+Set raise error timeout for read/write optations.
+
+This option is only relevant in read mode:
+if no data arrived in more than this time
+interval, raise error.
+
+@item tlpktdrop=@var{1|0}
+Too-late Packet Drop. When enabled on receiver, it skips
+missing packets that have not been delivered in time and
+delivers the following packets to the application when
+their time-to-play has come. It also sends a fake ACK to
+the sender. When enabled on sender and enabled on the
+receiving peer, the sender drops the older packets that
+have no chance of being delivered in time. It was
+automatically enabled in the sender if the receiver
+supports it.
+
+@item tsbpddelay
+Timestamp-based Packet Delivery Delay.
+Used to absorb burst of missed packet retransmission.
+
+@end table
+
+For more information see: @url{https://github.com/Haivision/srt}.
+
@section tcp

Transmission Control Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 2c1c0f6..8a3b748 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -398,6 +398,7 @@ OBJS-$(CONFIG_MD5_PROTOCOL) += md5proto.o
OBJS-$(CONFIG_MMSH_PROTOCOL) += mmsh.o mms.o asf.o
OBJS-$(CONFIG_MMST_PROTOCOL) += mmst.o mms.o asf.o
OBJS-$(CONFIG_PIPE_PROTOCOL) += file.o
+OBJS-$(CONFIG_OPENSRT_PROTOCOL) += opensrt.o
OBJS-$(CONFIG_RTMP_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
OBJS-$(CONFIG_RTMPE_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
OBJS-$(CONFIG_RTMPS_PROTOCOL) += rtmpproto.o rtmpdigest.o rtmppkt.o
diff --git a/libavformat/opensrt.c b/libavformat/opensrt.c
new file mode 100644
index 0000000..3f85c1c
--- /dev/null
+++ b/libavformat/opensrt.c
@@ -0,0 +1,549 @@
+/*
+ * This file is part of Libav.
+ *
+ * Libav 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.
+ *
+ * Libav 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 Libav; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * Haivision Open SRT (Secure Reliable Transport) protocol
+ */
+
+#include "avformat.h"
+#include "libavutil/avassert.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/opt.h"
+#include "libavutil/time.h"
+
+#include "internal.h"
+#include "network.h"
+#include "os_support.h"
+#include "url.h"
+#if HAVE_POLL_H
+#include <poll.h>
+#endif
+
+#include <srt/srt.h>
+
+enum SRTMode {
+ SRT_MODE_CALLER = 0,
+ SRT_MODE_LISTENER = 1,
+ SRT_MODE_RENDEZVOUS = 2
+};
+
+typedef struct SRTContext {
+ const AVClass *class;
+ int fd;
+ int eid;
+ int64_t rw_timeout;
+ int64_t listen_timeout;
+ int recv_buffer_size;
+ int send_buffer_size;
+
+ int64_t maxbw;
+ int pbkeylen;
+ char *passphrase;
+ int mss;
+ int ffs;
+ int ipttl;
+ int iptos;
+ int64_t inputbw;
+ int oheadbw;
+ int64_t tsbpddelay;
+ int tlpktdrop;
+ int nakreport;
+ int64_t connect_timeout;
+ enum SRTMode mode;
+} SRTContext;
+
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+#define OFFSET(x) offsetof(SRTContext, x)
+static const AVOption opensrt_options[] = {
+ { "rw_timeout", "Timeout of socket I/O operations", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "listen_timeout", "Connection awaiting timeout", OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "send_buffer_size", "Socket send buffer size (in bytes)", OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "recv_buffer_size", "Socket receive buffer size (in bytes)", OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "maxbw", "Maximum bandwidth (bytes per second) that the connection can use", OFFSET(maxbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "pbkeylen", "Crypto key len in bytes {16,24,32} Default: 16 (128-bit)", OFFSET(pbkeylen), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 32, .flags = D|E },
+ { "passphrase", "Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto", OFFSET(passphrase), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
+ { "mss", "The Maximum Segment Size", OFFSET(mss), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1500, .flags = D|E },
+ { "ffs", "Flight flag size (window size) (in bytes)", OFFSET(ffs), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
+ { "ipttl", "IP Time To Live", OFFSET(ipttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
+ { "iptos", "IP Type of Service", OFFSET(iptos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
+ { "inputbw", "Estimated input stream rate", OFFSET(inputbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "oheadbw", "MaxBW ceiling based on % over input stream rate", OFFSET(oheadbw), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, .flags = D|E },
+ { "tsbpddelay", "TsbPd receiver delay to absorb burst of missed packet retransmission", OFFSET(tsbpddelay), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "tlpktdrop", "Enable receiver pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, .flags = D|E },
+ { "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1, .flags = D|E },
+ { "connect_timeout", "Connect timeout. Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
+ { "mode", "Connection mode (caller, listener, rendezvous)", OFFSET(mode), AV_OPT_TYPE_INT, { .i64 = SRT_MODE_CALLER }, SRT_MODE_CALLER, SRT_MODE_RENDEZVOUS, .flags = D|E, "mode" },
+ { "caller", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_CALLER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
+ { "listener", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_LISTENER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
+ { "rendezvous", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_RENDEZVOUS }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
+ { NULL }
+};
+
+static int opensrt_neterrno(URLContext *h)
+{
+ int err = srt_getlasterror(NULL);
+ av_log(h, AV_LOG_ERROR, "%s\n", srt_getlasterror_str());
+ if (err == SRT_EASYNCRCV)
+ return AVERROR(EAGAIN);
+ return AVERROR_UNKNOWN;
+}
+
+static int opensrt_socket_nonblock(int socket, int enable)
+{
+ int ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &enable, sizeof(enable));
+ if (ret < 0)
+ return ret;
+ return srt_setsockopt(socket, 0, SRTO_RCVSYN, &enable, sizeof(enable));
+}
+
+static int opensrt_network_wait_fd(URLContext *h, int eid, int fd, int write)
+{
+ int ret, len = 1;
+ int modes = write ? SRT_EPOLL_OUT : SRT_EPOLL_IN;
+ SRTSOCKET ready[1];
+
+ if (srt_epoll_add_usock(eid, fd, &modes) < 0)
+ return opensrt_neterrno(h);
+ if (write) {
+ ret = srt_epoll_wait(eid, 0, 0, ready, &len, POLLING_TIME, 0, 0, 0, 0);
+ } else {
+ ret = srt_epoll_wait(eid, ready, &len, 0, 0, POLLING_TIME, 0, 0, 0, 0);
+ }
+ if (ret < 0) {
+ if (srt_getlasterror(NULL) == SRT_ETIMEOUT)
+ ret = AVERROR(EAGAIN);
+ else
+ ret = opensrt_neterrno(h);
+ } else {
+ ret = 0;
+ }
+ if (srt_epoll_remove_usock(eid, fd) < 0)
+ return opensrt_neterrno(h);
+ return ret;
+}
+
+/* TODO de-duplicate code from ff_network_wait_fd_timeout() */
+
+static int opensrt_network_wait_fd_timeout(URLContext *h, int eid, int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
+{
+ int ret;
+ int64_t wait_start = 0;
+
+ while (1) {
+ if (ff_check_interrupt(int_cb))
+ return AVERROR_EXIT;
+ ret = opensrt_network_wait_fd(h, eid, fd, write);
+ if (ret != AVERROR(EAGAIN))
+ return ret;
+ if (timeout > 0) {
+ if (!wait_start)
+ wait_start = av_gettime_relative();
+ else if (av_gettime_relative() - wait_start > timeout)
+ return AVERROR(ETIMEDOUT);
+ }
+ }
+}
+
+static int opensrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int timeout)
+{
+ int ret;
+ int reuse = 1;
+ if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, sizeof(reuse))) {
+ av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_REUSEADDR) failed\n");
+ }
+ ret = srt_bind(fd, addr, addrlen);
+ if (ret)
+ return opensrt_neterrno(h);
+
+ ret = srt_listen(fd, 1);
+ if (ret)
+ return opensrt_neterrno(h);
+
+ while ((ret = opensrt_network_wait_fd_timeout(h, eid, fd, 1, timeout, &h->interrupt_callback))) {
+ switch (ret) {
+ case AVERROR(ETIMEDOUT):
+ continue;
+ default:
+ return ret;
+ }
+ }
+
+ ret = srt_accept(fd, NULL, NULL);
+ if (ret < 0)
+ return opensrt_neterrno(h);
+ if (opensrt_socket_nonblock(ret, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "opensrt_socket_nonblock failed\n");
+
+ return ret;
+}
+
+static int opensrt_listen_connect(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next)
+{
+ int ret;
+
+ if (opensrt_socket_nonblock(fd, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
+
+ while ((ret = srt_connect(fd, addr, addrlen))) {
+ ret = opensrt_neterrno(h);
+ switch (ret) {
+ case AVERROR(EINTR):
+ if (ff_check_interrupt(&h->interrupt_callback))
+ return AVERROR_EXIT;
+ continue;
+ case AVERROR(EINPROGRESS):
+ case AVERROR(EAGAIN):
+ ret = opensrt_network_wait_fd_timeout(h, eid, fd, 1, timeout, &h->interrupt_callback);
+ if (ret < 0)
+ return ret;
+ ret = srt_getlasterror(NULL);
+ srt_clearlasterror();
+ if (ret != 0) {
+ char buf[128];
+ ret = AVERROR(ret);
+ av_strerror(ret, buf, sizeof(buf));
+ if (will_try_next)
+ av_log(h, AV_LOG_WARNING,
+ "Connection to %s failed (%s), trying next address\n",
+ h->filename, buf);
+ else
+ av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
+ h->filename, buf);
+ }
+ default:
+ return ret;
+ }
+ }
+ return ret;
+}
+
+static int opensrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, const void * optval, int optlen)
+{
+ if (srt_setsockopt(fd, 0, optname, optval, optlen) < 0) {
+ av_log(h, AV_LOG_ERROR, "failed to set option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+/* - The "POST" options can be altered any time on a connected socket.
+ They MAY have also some meaning when set prior to connecting; such
+ option is SRTO_RCVSYN, which makes connect/accept call asynchronous.
+ Because of that this option is treated special way in this app. */
+static int opensrt_set_options_post(URLContext *h, int fd)
+{
+ SRTContext *s = h->priv_data;
+
+ if ((s->inputbw >= 0 && opensrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) ||
+ (s->oheadbw >= 0 && opensrt_setsockopt(h, fd, SRTO_OHEADBW, "SRTO_OHEADBW", &s->oheadbw, sizeof(s->oheadbw)) < 0)) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+/* - The "PRE" options must be set prior to connecting and can't be altered
+ on a connected socket, however if set on a listening socket, they are
+ derived by accept-ed socket. */
+static int opensrt_set_options_pre(URLContext *h, int fd)
+{
+ SRTContext *s = h->priv_data;
+ int yes = 1;
+ int tsbpddelay = s->tsbpddelay / 1000;
+ int connect_timeout = s->connect_timeout;
+
+ if ((s->mode == SRT_MODE_RENDEZVOUS && opensrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) ||
+ (s->maxbw >= 0 && opensrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) ||
+ (s->pbkeylen >= 0 && opensrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
+ (s->passphrase && opensrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) ||
+ (s->mss >= 0 && opensrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) ||
+ (s->ffs >= 0 && opensrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) ||
+ (s->ipttl >= 0 && opensrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) ||
+ (s->iptos >= 0 && opensrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) ||
+ (tsbpddelay >= 0 && opensrt_setsockopt(h, fd, SRTO_TSBPDDELAY, "SRTO_TSBPDELAY", &tsbpddelay, sizeof(tsbpddelay)) < 0) ||
+ (s->tlpktdrop >= 0 && opensrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) ||
+ (s->nakreport >= 0 && opensrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) ||
+ (connect_timeout >= 0 && opensrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 )) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+
+static int opensrt_setup(URLContext *h, const char *uri, int flags)
+{
+ struct addrinfo hints = { 0 }, *ai, *cur_ai;
+ int port, fd = -1;
+ SRTContext *s = h->priv_data;
+ const char *p;
+ char buf[256];
+ int ret;
+ char hostname[1024],proto[1024],path[1024];
+ char portstr[10];
+ int open_timeout = 5000000;
+ int eid;
+
+ eid = srt_epoll_create();
+ if (eid < 0)
+ return opensrt_neterrno(h);
+ s->eid = eid;
+
+ av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
+ &port, path, sizeof(path), uri);
+ if (strcmp(proto, "srt"))
+ return AVERROR(EINVAL);
+ if (port <= 0 || port >= 65536) {
+ av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
+ return AVERROR(EINVAL);
+ }
+ p = strchr(uri, '?');
+ if (p) {
+ if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
+ s->rw_timeout = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
+ s->listen_timeout = strtol(buf, NULL, 10);
+ }
+ }
+ if (s->rw_timeout >= 0) {
+ open_timeout = h->rw_timeout = s->rw_timeout;
+ }
+ hints.ai_family = AF_UNSPEC;
+ hints.ai_socktype = SOCK_DGRAM;
+ snprintf(portstr, sizeof(portstr), "%d", port);
+ if (s->mode == SRT_MODE_LISTENER)
+ hints.ai_flags |= AI_PASSIVE;
+ ret = getaddrinfo(hostname[0] ? hostname : NULL, portstr, &hints, &ai);
+ if (ret) {
+ av_log(h, AV_LOG_ERROR,
+ "Failed to resolve hostname %s: %s\n",
+ hostname, gai_strerror(ret));
+ return AVERROR(EIO);
+ }
+
+ cur_ai = ai;
+
+ restart:
+
+ fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
+ if (fd < 0) {
+ ret = opensrt_neterrno(h);
+ goto fail;
+ }
+
+ if ((ret = opensrt_set_options_pre(h, fd)) < 0) {
+ goto fail;
+ }
+
+ /* Set the socket's send or receive buffer sizes, if specified.
+ If unspecified or setting fails, system default is used. */
+ if (s->recv_buffer_size > 0) {
+ srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size));
+ }
+ if (s->send_buffer_size > 0) {
+ srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size));
+ }
+ if (s->mode == SRT_MODE_LISTENER) {
+ // multi-client
+ if ((ret = opensrt_listen(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, open_timeout / 1000)) < 0)
+ goto fail1;
+ fd = ret;
+ } else {
+ if (s->mode == SRT_MODE_RENDEZVOUS) {
+ ret = srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
+ if (ret)
+ goto fail1;
+ }
+
+ if ((ret = opensrt_listen_connect(s->eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
+ open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) {
+ if (ret == AVERROR_EXIT)
+ goto fail1;
+ else
+ goto fail;
+ }
+ }
+ if ((ret = opensrt_set_options_post(h, fd)) < 0) {
+ goto fail;
+ }
+
+ h->is_streamed = 1;
+ s->fd = fd;
+
+ freeaddrinfo(ai);
+ return 0;
+
+ fail:
+ if (cur_ai->ai_next) {
+ /* Retry with the next sockaddr */
+ cur_ai = cur_ai->ai_next;
+ if (fd >= 0)
+ srt_close(fd);
+ ret = 0;
+ goto restart;
+ }
+ fail1:
+ if (fd >= 0)
+ srt_close(fd);
+ freeaddrinfo(ai);
+ return ret;
+}
+
+static int opensrt_open(URLContext *h, const char *uri, int flags)
+{
+ SRTContext *s = h->priv_data;
+ const char * p;
+ char buf[256];
+
+ if (srt_startup() < 0) {
+ return AVERROR_UNKNOWN;
+ }
+
+ /* SRT options (srt/srt.h) */
+ p = strchr(uri, '?');
+ if (p) {
+ if (av_find_info_tag(buf, sizeof(buf), "maxbw", p)) {
+ s->maxbw = strtoll(buf, NULL, 0);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "pbkeylen", p)) {
+ s->pbkeylen = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "passphrase", p)) {
+ s->passphrase = av_strndup(buf, strlen(buf));
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "mss", p)) {
+ s->mss = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "ffs", p)) {
+ s->ffs = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "ipttl", p)) {
+ s->ipttl = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "iptos", p)) {
+ s->iptos = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "inputbw", p)) {
+ s->inputbw = strtoll(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "oheadbw", p)) {
+ s->oheadbw = strtoll(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "tsbpddelay", p)) {
+ s->tsbpddelay = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "tlpktdrop", p)) {
+ s->tlpktdrop = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "nakreport", p)) {
+ s->nakreport = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "connect_timeout", p)) {
+ s->connect_timeout = strtol(buf, NULL, 10);
+ }
+ if (av_find_info_tag(buf, sizeof(buf), "mode", p)) {
+ if (!strcmp(buf, "caller")) {
+ s->mode = SRT_MODE_CALLER;
+ } else if (!strcmp(buf, "listener")) {
+ s->mode = SRT_MODE_LISTENER;
+ } else if (!strcmp(buf, "rendezvous")) {
+ s->mode = SRT_MODE_RENDEZVOUS;
+ } else {
+ return AVERROR(EIO);
+ }
+ }
+ }
+ return opensrt_setup(h, uri, flags);
+}
+
+static int opensrt_read(URLContext *h, uint8_t *buf, int size)
+{
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = opensrt_network_wait_fd_timeout(h, s->eid, s->fd, 0, h->rw_timeout, &h->interrupt_callback);
+ if (ret)
+ return ret;
+ }
+
+ ret = srt_recvmsg(s->fd, buf, size);
+ if (ret < 0) {
+ ret = opensrt_neterrno(h);
+ }
+
+ return ret;
+}
+
+static int opensrt_write(URLContext *h, const uint8_t *buf, int size)
+{
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = opensrt_network_wait_fd_timeout(h, s->eid, s->fd, 1, h->rw_timeout, &h->interrupt_callback);
+ if (ret)
+ return ret;
+ }
+
+ ret = srt_sendmsg(s->fd, buf, size, -1, 0);
+ if (ret < 0) {
+ ret = opensrt_neterrno(h);
+ }
+
+ return ret;
+}
+
+static int opensrt_close(URLContext *h)
+{
+ SRTContext *s = h->priv_data;
+
+ srt_close(s->fd);
+
+ srt_epoll_release(s->eid);
+
+ srt_cleanup();
+
+ return 0;
+}
+
+static int opensrt_get_file_handle(URLContext *h)
+{
+ SRTContext *s = h->priv_data;
+ return s->fd;
+}
+
+static const AVClass opensrt_class = {
+ .class_name = "opensrt",
+ .item_name = av_default_item_name,
+ .option = opensrt_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const URLProtocol ff_opensrt_protocol = {
+ .name = "srt",
+ .url_open = opensrt_open,
+ .url_read = opensrt_read,
+ .url_write = opensrt_write,
+ .url_close = opensrt_close,
+ .url_get_file_handle = opensrt_get_file_handle,
+ .priv_data_size = sizeof(SRTContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &opensrt_class,
+};
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 8ea5c0e..c2ae72d 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -38,6 +38,7 @@ extern const URLProtocol ff_mmsh_protocol;
extern const URLProtocol ff_mmst_protocol;
extern const URLProtocol ff_md5_protocol;
extern const URLProtocol ff_pipe_protocol;
+extern const URLProtocol ff_opensrt_protocol;
extern const URLProtocol ff_rtmp_protocol;
extern const URLProtocol ff_rtmpe_protocol;
extern const URLProtocol ff_rtmps_protocol;
--
1.8.3.1
Diego Biurrun
2018-03-26 15:14:40 UTC
Permalink
Post by Luca Barbato
--- a/configure
+++ b/configure
@@ -4710,6 +4714,7 @@ enabled omx && require_header OMX_Core.h
+enabled opensrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
Why do you call this thing opensrt when it calls itself libsrt?

Diego
nablet developer
2018-03-26 15:16:06 UTC
Permalink
Post by Diego Biurrun
Post by Luca Barbato
--- a/configure
+++ b/configure
@@ -4710,6 +4714,7 @@ enabled omx && require_header OMX_Core.h
+enabled opensrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
Why do you call this thing opensrt when it calls itself libsrt?
names srt and libsrt were found confusing and misleading, because of
similar acronyms used for other
multimedia related things which are pretty well-known and wide-spread
already (e.g. SRT subtitles or
SRTP protocol). as result, maintainers/reviewers asked to change name to
avoid confusion, and Haivision
recommended to use "opensrt" naming in order to distinguish from other
similar acronyms.
Diego Biurrun
2018-03-26 15:42:30 UTC
Permalink
Post by nablet developer
Post by Diego Biurrun
Post by Luca Barbato
--- a/configure
+++ b/configure
@@ -4710,6 +4714,7 @@ enabled omx && require_header OMX_Core.h
+enabled opensrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
Why do you call this thing opensrt when it calls itself libsrt?
names srt and libsrt were found confusing and misleading, because of
similar acronyms used for other multimedia related things which are
pretty well-known and wide-spread already (e.g. SRT subtitles or SRTP
protocol). as result, maintainers/reviewers asked to change name to
avoid confusion, and Haivision recommended to use "opensrt" naming in
order to distinguish from other similar acronyms.
The problem is that Haivision does not use "opensrt" as name, they use
"SRT/srt" and libsrt. Using a different name inside libav does not
really help in reducing that potential for confusion. If Haivision
recommends "opensrt", why don't they change the name of their library?
Better yet, why don't they change the name of the protocol?

Notice that what I gathered from the discussion was people complaining
about the bad naming choice, not suggesting "opensrt" as the alternative.

I have asked this before: what is your relationship to Haivision?

Diego
Luca Barbato
2018-03-26 17:05:29 UTC
Permalink
Post by nablet developer
names srt and libsrt were found confusing and misleading, because of
similar acronyms used for other multimedia related things which are
pretty well-known and wide-spread already (e.g. SRT subtitles or SRTP
protocol). as result, maintainers/reviewers asked to change name to
avoid confusion, and Haivision recommended to use "opensrt" naming in
order to distinguish from other similar acronyms.
One is SubRip text, quite a different beast.

SRTP was already a bad name since RTPs and RTSP existed before and are
even closely related.

Right now I'm less concerned about spending time introducing yet another
potentially unsearchable variant since gstreamer is using srt/libsrt
since a while and just feeding any search engine worth its name with
"srt protocol" produces non-misleading links.

lu
Luca Barbato
2018-03-26 16:37:18 UTC
Permalink
Post by Luca Barbato
protocol requires libsrt (https://github.com/Haivision/srt) to be
installed
---
From a quick search across engines:

- "srt protocol" leads to the right thing.

- gstreamer references srt/libsrt in their components and in their
documentation.

If there aren't other non-cosmetic issues I'd merge it with the libsrt
namespace and be done with that.

I might ask you help so we can have some additional information about
how to properly use the protocol in the wiki.

lu
Diego Biurrun
2018-03-29 06:29:07 UTC
Permalink
Post by Luca Barbato
protocol requires libsrt (https://github.com/Haivision/srt) to be
installed
Luca and I pushed a cleaned-up version of this yesterday.

Diego

Loading...