[FFmpeg-cvslog] Merge commit 'a2fc8dbae85339d1b418d296f2982b6c04c53c57'
James Almer
git at videolan.org
Fri Mar 30 03:59:43 EEST 2018
ffmpeg | branch: master | James Almer <jamrial at gmail.com> | Thu Mar 29 21:56:19 2018 -0300| [a123e576a485931013c9fae85025d0e78ff3102d] | committer: James Almer
Merge commit 'a2fc8dbae85339d1b418d296f2982b6c04c53c57'
* commit 'a2fc8dbae85339d1b418d296f2982b6c04c53c57':
Add Haivision SRT protocol
Merged-by: James Almer <jamrial at gmail.com>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=a123e576a485931013c9fae85025d0e78ff3102d
---
Changelog | 1 +
configure | 5 +
doc/protocols.texi | 140 +++++++++++++
libavformat/Makefile | 1 +
libavformat/libsrt.c | 546 ++++++++++++++++++++++++++++++++++++++++++++++++
libavformat/protocols.c | 1 +
6 files changed, 694 insertions(+)
diff --git a/Changelog b/Changelog
index 2869dce386..200866d873 100644
--- a/Changelog
+++ b/Changelog
@@ -51,6 +51,7 @@ version <next>:
- AV1 Support through libaom
- E-AC-3 dependent frames support
- bitstream filter for extracting E-AC-3 core
+- Haivision SRT protocol via libsrt
version 3.4:
diff --git a/configure b/configure
index a92ac6acb7..99570a1415 100755
--- a/configure
+++ b/configure
@@ -257,6 +257,7 @@ External library support:
--enable-libsnappy enable Snappy compression, needed for hap encoding [no]
--enable-libsoxr enable Include libsoxr resampling [no]
--enable-libspeex enable Speex de/encoding via libspeex [no]
+ --enable-libsrt enable Haivision SRT protocol via libsrt [no]
--enable-libssh enable SFTP protocol via libssh [no]
--enable-libtesseract enable Tesseract, needed for ocr filter [no]
--enable-libtheora enable Theora encoding via libtheora [no]
@@ -1705,6 +1706,7 @@ EXTERNAL_LIBRARY_LIST="
libsnappy
libsoxr
libspeex
+ libsrt
libssh
libtesseract
libtheora
@@ -3246,6 +3248,8 @@ libssh_protocol_deps="libssh"
libtls_conflict="openssl gnutls"
mmsh_protocol_select="http_protocol"
mmst_protocol_select="network"
+libsrt_protocol_deps="libsrt"
+libsrt_protocol_select="network"
rtmp_protocol_conflict="librtmp_protocol"
rtmp_protocol_select="tcp_protocol"
rtmp_protocol_suggest="zlib"
@@ -6021,6 +6025,7 @@ enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnap
enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init
enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
+enabled libsrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
enabled libtls && require_pkg_config libtls libtls tls.h tls_configure
diff --git a/doc/protocols.texi b/doc/protocols.texi
index c24dc74505..e19504d073 100644
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@ -1155,6 +1155,146 @@ If set to any value, listen for an incoming connection. Outgoing connection is d
Set the maximum number of streams. By default no limit is set.
@end table
+ at section srt
+
+Haivision Secure Reliable Transport Protocol via libsrt.
+
+The supported syntax for a SRT URL is:
+ at example
+srt://@var{hostname}:@var{port}[?@var{options}]
+ at end example
+
+ at var{options} contains a list of &-separated options of the form
+ at var{key}=@var{val}.
+
+or
+
+ at example
+ at var{options} srt://@var{hostname}:@var{port}
+ at end example
+
+ at var{options} contains a list of '- at var{key} @var{val}'
+options.
+
+This protocol accepts the following options.
+
+ at table @option
+ at 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).
+
+ at 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
+ at 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.
+
+ at item inputbw=@var{bytes/seconds}
+Sender nominal input rate, in bytes per seconds. Used along with
+ at 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:
+ at option{inputbw} * (100 + @option{oheadbw}) / 100
+if @option{inputbw} is not set while @option{maxbw} is set to
+relative (0), the actual input rate is evaluated inside
+the library. Default value is 0.
+
+ at item iptos=@var{tos}
+IP Type of Service. Applies to sender only. Default value is 0xB8.
+
+ at item ipttl=@var{ttl}
+IP Time To Live. Applies to sender only. Default value is 64.
+
+ at item listen_timeout
+Set socket listen timeout.
+
+ at 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)
+
+ at item mode=@var{caller|listener|rendezvous}
+Connection mode.
+ at option{caller} opens client connection.
+ at option{listener} starts server to listen for incoming connections.
+ at option{rendezvous} use Rendez-Vous connection mode.
+Default value is caller.
+
+ at 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.
+
+ at 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.
+
+ at item oheadbw=@var{percents}
+Recovery bandwidth overhead above input rate, in percents.
+See @option{inputbw}. Default value is 25%.
+
+ at 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).
+
+ at 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.
+
+ at item recv_buffer_size=@var{bytes}
+Set receive buffer size, expressed in bytes.
+
+ at item send_buffer_size=@var{bytes}
+Set send buffer size, expressed in bytes.
+
+ at 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.
+
+ at 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.
+
+ at item tsbpddelay
+Timestamp-based Packet Delivery Delay.
+Used to absorb burst of missed packet retransmission.
+
+ at end table
+
+For more information see: @url{https://github.com/Haivision/srt}.
+
@section srtp
Secure Real-time Transport Protocol.
diff --git a/libavformat/Makefile b/libavformat/Makefile
index 39ec68c28b..af0823a7db 100644
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@ -566,6 +566,7 @@ OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBRTMPS_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBRTMPT_PROTOCOL) += librtmp.o
OBJS-$(CONFIG_LIBRTMPTE_PROTOCOL) += librtmp.o
+OBJS-$(CONFIG_LIBSRT_PROTOCOL) += libsrt.o
OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o
OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o
diff --git a/libavformat/libsrt.c b/libavformat/libsrt.c
new file mode 100644
index 0000000000..0f9529d263
--- /dev/null
+++ b/libavformat/libsrt.c
@@ -0,0 +1,546 @@
+/*
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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.
+ *
+ * FFmpeg 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 FFmpeg; 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 <srt/srt.h>
+
+#include "libavutil/avassert.h"
+#include "libavutil/opt.h"
+#include "libavutil/parseutils.h"
+#include "libavutil/time.h"
+
+#include "avformat.h"
+#include "internal.h"
+#include "network.h"
+#include "os_support.h"
+#include "url.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 libsrt_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 libsrt_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 libsrt_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 libsrt_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 libsrt_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 = libsrt_neterrno(h);
+ } else {
+ ret = 0;
+ }
+ if (srt_epoll_remove_usock(eid, fd) < 0)
+ return libsrt_neterrno(h);
+ return ret;
+}
+
+/* TODO de-duplicate code from ff_network_wait_fd_timeout() */
+
+static int libsrt_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 = libsrt_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 libsrt_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 libsrt_neterrno(h);
+
+ ret = srt_listen(fd, 1);
+ if (ret)
+ return libsrt_neterrno(h);
+
+ while ((ret = libsrt_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 libsrt_neterrno(h);
+ if (libsrt_socket_nonblock(ret, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");
+
+ return ret;
+}
+
+static int libsrt_listen_connect(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next)
+{
+ int ret;
+
+ if (libsrt_socket_nonblock(fd, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
+
+ while ((ret = srt_connect(fd, addr, addrlen))) {
+ ret = libsrt_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 = libsrt_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 libsrt_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 libsrt_set_options_post(URLContext *h, int fd)
+{
+ SRTContext *s = h->priv_data;
+
+ if ((s->inputbw >= 0 && libsrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) ||
+ (s->oheadbw >= 0 && libsrt_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 libsrt_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 && libsrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) ||
+ (s->maxbw >= 0 && libsrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) ||
+ (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
+ (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) ||
+ (s->mss >= 0 && libsrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) ||
+ (s->ffs >= 0 && libsrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) ||
+ (s->ipttl >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) ||
+ (s->iptos >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) ||
+ (tsbpddelay >= 0 && libsrt_setsockopt(h, fd, SRTO_TSBPDDELAY, "SRTO_TSBPDELAY", &tsbpddelay, sizeof(tsbpddelay)) < 0) ||
+ (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) ||
+ (s->nakreport >= 0 && libsrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) ||
+ (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 )) {
+ return AVERROR(EIO);
+ }
+ return 0;
+}
+
+
+static int libsrt_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 libsrt_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 = libsrt_neterrno(h);
+ goto fail;
+ }
+
+ if ((ret = libsrt_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 = libsrt_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 = libsrt_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 = libsrt_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 libsrt_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 libsrt_setup(h, uri, flags);
+}
+
+static int libsrt_read(URLContext *h, uint8_t *buf, int size)
+{
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = libsrt_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 = libsrt_neterrno(h);
+ }
+
+ return ret;
+}
+
+static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
+{
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = libsrt_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 = libsrt_neterrno(h);
+ }
+
+ return ret;
+}
+
+static int libsrt_close(URLContext *h)
+{
+ SRTContext *s = h->priv_data;
+
+ srt_close(s->fd);
+
+ srt_epoll_release(s->eid);
+
+ srt_cleanup();
+
+ return 0;
+}
+
+static int libsrt_get_file_handle(URLContext *h)
+{
+ SRTContext *s = h->priv_data;
+ return s->fd;
+}
+
+static const AVClass libsrt_class = {
+ .class_name = "libsrt",
+ .item_name = av_default_item_name,
+ .option = libsrt_options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
+
+const URLProtocol ff_libsrt_protocol = {
+ .name = "srt",
+ .url_open = libsrt_open,
+ .url_read = libsrt_read,
+ .url_write = libsrt_write,
+ .url_close = libsrt_close,
+ .url_get_file_handle = libsrt_get_file_handle,
+ .priv_data_size = sizeof(SRTContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &libsrt_class,
+};
diff --git a/libavformat/protocols.c b/libavformat/protocols.c
index 669d74d5a8..ad95659795 100644
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@ -65,6 +65,7 @@ extern const URLProtocol ff_librtmpe_protocol;
extern const URLProtocol ff_librtmps_protocol;
extern const URLProtocol ff_librtmpt_protocol;
extern const URLProtocol ff_librtmpte_protocol;
+extern const URLProtocol ff_libsrt_protocol;
extern const URLProtocol ff_libssh_protocol;
extern const URLProtocol ff_libsmbclient_protocol;
======================================================================
diff --cc Changelog
index 2869dce386,53562a1aa0..200866d873
--- a/Changelog
+++ b/Changelog
@@@ -2,399 -2,40 +2,400 @@@ Entries are sorted chronologically fro
releases are sorted from youngest to oldest.
version <next>:
-- Support for spherical videos
-- Intel QSV-accelerated VP8 and VC-1 decoding
-- VAAPI-accelerated VP8 and HEVC decoding
-- VAAPI-accelerated deinterlacing
-- config.log and other configuration files moved into avbuild/ directory
-- VAAPI-accelerated MPEG-2 and VP8 encoding
-- Apple Pixlet decoder
-- The x86 assembler default switched from yasm to nasm, pass
- --x86asmexe=yasm to configure to restore the old behavior.
-- Cineform HD decoder
-- VP9 superframe split/merge bitstream filters
-- FM Screen Capture Codec decoder
-- ClearVideo decoder (I-frames only)
-- support for decoding through D3D11VA in avconv
-- Cinepak encoder
+- Bitstream filters for editing metadata in H.264, HEVC and MPEG-2 streams
+- Dropped support for OpenJPEG versions 2.0 and below. Using OpenJPEG now
+ requires 2.1 (or later) and pkg-config.
+- VDA dropped (use VideoToolbox instead)
+- MagicYUV encoder
+- Raw AMR-NB and AMR-WB demuxers
+- TiVo ty/ty+ demuxer
- Intel QSV-accelerated MJPEG encoding
-- NVIDIA CUVID-accelerated H.264 and HEVC decoding
+- PCE support for extended channel layouts in the AAC encoder
+- native aptX and aptX HD encoder and decoder
+- Raw aptX and aptX HD muxer and demuxer
+- NVIDIA NVDEC-accelerated H.264, HEVC, MJPEG, MPEG-1/2/4, VC1, VP8/9 hwaccel decoding
- Intel QSV-accelerated overlay filter
+- mcompand audio filter
+- acontrast audio filter
+- OpenCL overlay filter
+- video mix filter
+- video normalize filter
+- audio lv2 wrapper filter
+- VAAPI MJPEG and VP8 decoding
+- AMD AMF H.264 and HEVC encoders
+- video fillborders filter
+- video setrange filter
+- nsp demuxer
+- support LibreSSL (via libtls)
+- AVX-512/ZMM support added
+- Dropped support for building for Windows XP. The minimum supported Windows
+ version is Windows Vista.
+- deconvolve video filter
+- entropy video filter
+- hilbert audio filter source
+- aiir audio filter
+- aiff: add support for CD-ROM XA ADPCM
+- Removed the ffserver program
+- Removed the ffmenc and ffmdec muxer and demuxer
+- VideoToolbox HEVC encoder and hwaccel
+- VAAPI-accelerated ProcAmp (color balance), denoise and sharpness filters
+- Add android_camera indev
+- codec2 en/decoding via libcodec2
+- muxer/demuxer for raw codec2 files and .c2 files
+- Moved nvidia codec headers into an external repository.
+ They can be found at http://git.videolan.org/?p=ffmpeg/nv-codec-headers.git
+- native SBC encoder and decoder
+- drmeter audio filter
+- hapqa_extract bitstream filter
+- filter_units bitstream filter
- AV1 Support through libaom
+- E-AC-3 dependent frames support
+- bitstream filter for extracting E-AC-3 core
+ - Haivision SRT protocol via libsrt
-version 12:
-- aliases and defaults for Ogg subtypes (opus, spx)
-- HEVC/H.265 RTP payload format (draft v6) packetizer and depacketizer
-- avplay now exits by default at the end of playback
-- XCB-based screen-grabber
-- creating DASH compatible fragmented MP4, MPEG-DASH segmenting muxer
-- H.261 RTP payload format (RFC 4587) depacketizer and experimental packetizer
+version 3.4:
+- deflicker video filter
+- doubleweave video filter
+- lumakey video filter
+- pixscope video filter
+- oscilloscope video filter
+- config.log and other configuration files moved into ffbuild/ directory
+- update cuvid/nvenc headers to Video Codec SDK 8.0.14
+- afir audio filter
+- scale_cuda CUDA based video scale filter
+- librsvg support for svg rasterization
+- crossfeed audio filter
+- spec compliant VP9 muxing support in MP4
+- remove the libnut muxer/demuxer wrappers
+- remove the libschroedinger encoder/decoder wrappers
+- surround audio filter
+- sofalizer filter switched to libmysofa
+- Gremlin Digital Video demuxer and decoder
+- headphone audio filter
+- superequalizer audio filter
+- roberts video filter
+- The x86 assembler default switched from yasm to nasm, pass
+ --x86asmexe=yasm to configure to restore the old behavior.
+- additional frame format support for Interplay MVE movies
+- support for decoding through D3D11VA in ffmpeg
+- limiter video filter
+- libvmaf video filter
+- Dolby E decoder and SMPTE 337M demuxer
+- unpremultiply video filter
+- tlut2 video filter
+- floodfill video filter
+- pseudocolor video filter
+- raw G.726 muxer and demuxer, left- and right-justified
+- NewTek NDI input/output device
+- Some video filters with several inputs now use a common set of options:
+ blend, libvmaf, lut3d, overlay, psnr, ssim.
+ They must always be used by name.
+- FITS demuxer and decoder
+- FITS muxer and encoder
+- add --disable-autodetect build switch
+- drop deprecated qtkit input device (use avfoundation instead)
+- despill video filter
+- haas audio filter
+- SUP/PGS subtitle muxer
+- convolve video filter
+- VP9 tile threading support
+- KMS screen grabber
+- CUDA thumbnail filter
+- V4L2 mem2mem HW assisted codecs
+- Rockchip MPP hardware decoding
+- vmafmotion video filter
+- use MIME type "G726" for little-endian G.726, "AAL2-G726" for big-endian G.726
+
+
+version 3.3:
+- CrystalHD decoder moved to new decode API
+- add internal ebur128 library, remove external libebur128 dependency
+- Pro-MPEG CoP #3-R2 FEC protocol
+- premultiply video filter
+- Support for spherical videos
+- configure now fails if autodetect-libraries are requested but not found
+- PSD Decoder
+- 16.8 floating point pcm decoder
+- 24.0 floating point pcm decoder
+- Apple Pixlet decoder
+- QDMC audio decoder
+- NewTek SpeedHQ decoder
+- MIDI Sample Dump Standard demuxer
+- readeia608 filter
+- Sample Dump eXchange demuxer
+- abitscope multimedia filter
+- Scenarist Closed Captions demuxer and muxer
+- threshold filter
+- midequalizer filter
+- Optimal Huffman tables for (M)JPEG encoding
+- VAAPI-accelerated MPEG-2 and VP8 encoding
+- FM Screen Capture Codec decoder
+- native Opus encoder
+- ScreenPressor decoder
+- incomplete ClearVideo decoder
+- Intel QSV video scaling and deinterlacing filters
+- Support MOV with multiple sample description tables
+- XPM decoder
+- Removed the legacy X11 screen grabber, use XCB instead
+- MPEG-7 Video Signature filter
+- Removed asyncts filter (use af_aresample instead)
+- Intel QSV-accelerated VP8 video decoding
+- VAAPI-accelerated deinterlacing
+
+
+version 3.2:
+- libopenmpt demuxer
+- tee protocol
+- Changed metadata print option to accept general urls
+- Alias muxer for Ogg Video (.ogv)
+- VP8 in Ogg muxing
+- curves filter doesn't automatically insert points at x=0 and x=1 anymore
+- 16-bit support in curves filter and selectivecolor filter
+- OpenH264 decoder wrapper
+- MediaCodec H.264/HEVC/MPEG-4/VP8/VP9 hwaccel
+- True Audio (TTA) muxer
+- crystalizer audio filter
+- acrusher audio filter
+- bitplanenoise video filter
+- floating point support in als decoder
+- fifo muxer
+- maskedclamp filter
+- hysteresis filter
+- lut2 filter
+- yuvtestsrc filter
+- CUDA CUVID H.263/VP8/VP9/10 bit HEVC (Dithered) Decoding
+- vaguedenoiser filter
+- added threads option per filter instance
+- weave filter
+- gblur filter
+- avgblur filter
+- sobel and prewitt filter
+- MediaCodec HEVC/MPEG-4/VP8/VP9 decoding
+- Meridian Lossless Packing (MLP) / TrueHD encoder
+- Non-Local Means (nlmeans) denoising filter
+- sdl2 output device and ffplay support
+- sdl1 output device and sdl1 support removed
+- extended mov edit list support
+- libfaac encoder removed
+- Matroska muxer now writes CRC32 elements by default in all Level 1 elements
+- sidedata video and asidedata audio filter
+- Changed mapping of rtp MIME type G726 to codec g726le.
+- spec compliant VAAPI/DXVA2 VC-1 decoding of slices in frame-coded images
+
+
+version 3.1:
+- DXVA2-accelerated HEVC Main10 decoding
+- fieldhint filter
+- loop video filter and aloop audio filter
+- Bob Weaver deinterlacing filter
+- firequalizer filter
+- datascope filter
+- bench and abench filters
+- ciescope filter
+- protocol blacklisting API
+- MediaCodec H264 decoding
+- VC-2 HQ RTP payload format (draft v1) depacketizer and packetizer
+- VP9 RTP payload format (draft v2) packetizer
+- AudioToolbox audio decoders
+- AudioToolbox audio encoders
+- coreimage filter (GPU based image filtering on OSX)
+- libdcadec removed
+- bitstream filter for extracting DTS core
+- ADPCM IMA DAT4 decoder
+- musx demuxer
+- aix demuxer
+- remap filter
+- hash and framehash muxers
+- colorspace filter
+- hdcd filter
+- readvitc filter
+- VAAPI-accelerated format conversion and scaling
+- libnpp/CUDA-accelerated format conversion and scaling
+- Duck TrueMotion 2.0 Real Time decoder
+- Wideband Single-bit Data (WSD) demuxer
+- VAAPI-accelerated H.264/HEVC/MJPEG encoding
+- DTS Express (LBR) decoder
+- Generic OpenMAX IL encoder with support for Raspberry Pi
+- IFF ANIM demuxer & decoder
+- Direct Stream Transfer (DST) decoder
+- loudnorm filter
+- MTAF demuxer and decoder
+- MagicYUV decoder
+- OpenExr improvements (tile data and B44/B44A support)
+- BitJazz SheerVideo decoder
+- CUDA CUVID H264/HEVC decoder
+- 10-bit depth support in native utvideo decoder
+- libutvideo wrapper removed
+- YUY2 Lossless Codec decoder
+- VideoToolbox H.264 encoder
+
+
+version 3.0:
+- Common Encryption (CENC) MP4 encoding and decoding support
+- DXV decoding
+- extrastereo filter
+- ocr filter
+- alimiter filter
+- stereowiden filter
+- stereotools filter
+- rubberband filter
+- tremolo filter
+- agate filter
+- chromakey filter
+- maskedmerge filter
+- Screenpresso SPV1 decoding
+- chromaprint fingerprinting muxer
+- ffplay dynamic volume control
+- displace filter
+- selectivecolor filter
+- extensive native AAC encoder improvements and removal of experimental flag
+- ADPCM PSX decoder
+- 3dostr, dcstr, fsb, genh, vag, xvag, ads, msf, svag & vpk demuxer
+- zscale filter
+- wve demuxer
+- zero-copy Intel QSV transcoding in ffmpeg
+- shuffleframes filter
+- SDX2 DPCM decoder
+- vibrato filter
+- innoHeim/Rsupport Screen Capture Codec decoder
+- ADPCM AICA decoder
+- Interplay ACM demuxer and audio decoder
+- XMA1 & XMA2 decoder
+- realtime filter
+- anoisesrc audio filter source
+- IVR demuxer
+- compensationdelay filter
+- acompressor filter
+- support encoding 16-bit RLE SGI images
+- apulsator filter
+- sidechaingate audio filter
+- mipsdspr1 option has been renamed to mipsdsp
+- aemphasis filter
+- mips32r5 option has been removed
+- mips64r6 option has been removed
+- DXVA2-accelerated VP9 decoding
+- SOFAlizer: virtual binaural acoustics filter
+- VAAPI VP9 hwaccel
+- audio high-order multiband parametric equalizer
+- automatic bitstream filtering
+- showspectrumpic filter
+- libstagefright support removed
+- spectrumsynth filter
+- ahistogram filter
+- only seek with the right mouse button in ffplay
+- toggle full screen when double-clicking with the left mouse button in ffplay
+- afftfilt filter
+- convolution filter
+- libquvi support removed
+- support for dvaudio in wav and avi
+- libaacplus and libvo-aacenc support removed
+- Cineform HD decoder
+- new DCA decoder with full support for DTS-HD extensions
+- significant performance improvements in Windows Television (WTV) demuxer
+- nnedi deinterlacer
+- streamselect video and astreamselect audio filter
+- swaprect filter
+- metadata video and ametadata audio filter
+- SMPTE VC-2 HQ profile support for the Dirac decoder
+- SMPTE VC-2 native encoder supporting the HQ profile
+
+
+version 2.8:
+- colorkey video filter
+- BFSTM/BCSTM demuxer
+- little-endian ADPCM_THP decoder
+- Hap decoder and encoder
+- DirectDraw Surface image/texture decoder
+- ssim filter
+- optional new ASF demuxer
+- showvolume filter
+- Many improvements to the JPEG 2000 decoder
+- Go2Meeting decoding support
+- adrawgraph audio and drawgraph video filter
+- removegrain video filter
+- Intel QSV-accelerated MPEG-2 video and HEVC encoding
+- Intel QSV-accelerated MPEG-2 video and HEVC decoding
+- Intel QSV-accelerated VC-1 video decoding
+- libkvazaar HEVC encoder
+- erosion, dilation, deflate and inflate video filters
+- Dynamic Audio Normalizer as dynaudnorm filter
+- Reverse video and areverse audio filter
+- Random filter
+- deband filter
+- AAC fixed-point decoding
+- sidechaincompress audio filter
+- bitstream filter for converting HEVC from MP4 to Annex B
+- acrossfade audio filter
+- allyuv and allrgb video sources
+- atadenoise video filter
+- OS X VideoToolbox support
+- aphasemeter filter
+- showfreqs filter
+- vectorscope filter
+- waveform filter
+- hstack and vstack filter
+- Support DNx100 (1440x1080 at 8)
+- VAAPI hevc hwaccel
+- VDPAU hevc hwaccel
+- framerate filter
+- Switched default encoders for webm to VP9 and Opus
+- Removed experimental flag from the JPEG 2000 encoder
+
+
+version 2.7:
+- FFT video filter
+- TDSC decoder
+- DTS lossless extension (XLL) decoding (not lossless, disabled by default)
+- showwavespic filter
+- DTS decoding through libdcadec
+- Drop support for nvenc API before 5.0
+- nvenc HEVC encoder
+- Detelecine filter
+- Intel QSV-accelerated H.264 encoding
+- MMAL-accelerated H.264 decoding
+- basic APNG encoder and muxer with default extension "apng"
+- unpack DivX-style packed B-frames in MPEG-4 bitstream filter
+- WebM Live Chunk Muxer
+- nvenc level and tier options
+- chorus filter
+- Canopus HQ/HQA decoder
+- Automatically rotate videos based on metadata in ffmpeg
+- improved Quickdraw compatibility
+- VP9 high bit-depth and extended colorspaces decoding support
+- WebPAnimEncoder API when available for encoding and muxing WebP
+- Direct3D11-accelerated decoding
+- Support Secure Transport
+- Multipart JPEG demuxer
+
+
+version 2.6:
+- nvenc encoder
+- 10bit spp filter
+- colorlevels filter
+- RIFX format for *.wav files
- RTP/mpegts muxer
-- VP8 in Ogg demuxing
+- non continuous cache protocol support
+- tblend filter
+- cropdetect support for non 8bpp, absolute (if limit >= 1) and relative (if limit < 1.0) threshold
+- Camellia symmetric block cipher
- OpenH264 encoder wrapper
+- VOC seeking support
+- Closed caption Decoder
+- fspp, uspp, pp7 MPlayer postprocessing filters ported to native filters
+- showpalette filter
+- Twofish symmetric block cipher
- Support DNx100 (960x720 at 8)
-- Direct3D11-accelerated decoding
+- eq2 filter ported from libmpcodecs as eq filter
+- removed libmpcodecs
+- Changed default DNxHD colour range in QuickTime .mov derivatives to mpeg range
+- ported softpulldown filter from libmpcodecs as repeatfields filter
+- dcshift filter
+- RTP depacketizer for loss tolerant payload format for MP3 audio (RFC 5219)
+- RTP depacketizer for AC3 payload format (RFC 4184)
+- palettegen and paletteuse filters
+- VP9 RTP payload format (draft 0) experimental depacketizer
+- RTP depacketizer for DV (RFC 6469)
- DXVA2-accelerated HEVC decoding
- AAC ELD 480 decoding
- Intel QSV-accelerated H.264 decoding
diff --cc configure
index a92ac6acb7,7612a6052c..99570a1415
--- a/configure
+++ b/configure
@@@ -198,134 -180,73 +198,135 @@@ External library support
libraries must be explicitly enabled.
Also note that the following help text describes the purpose of the libraries
- themselves, not all their features will necessarily be usable by Libav.
-
- --enable-avisynth video frameserver
- --enable-avxsynth Linux version of AviSynth
- --enable-bzlib bzip2 compression [autodetect]
- --enable-frei0r video filtering plugins
- --enable-gnutls crypto
- --enable-libaom AV1 video encoding/decoding
- --enable-libbs2b Bauer stereophonic-to-binaural DSP
- --enable-libcdio audio CD input
- --enable-libdc1394 IEEE 1394/Firewire camera input
- --enable-libdcadec DCA audio decoding
- --enable-libfaac AAC audio encoding
- --enable-libfdk-aac AAC audio encoding/decoding
- --enable-libfontconfig font configuration and management
- --enable-libfreetype font rendering
- --enable-libgsm GSM audio encoding/decoding
- --enable-libhdcd HDCD decoding filter
- --enable-libilbc ILBC audio encoding/decoding
- --enable-libjack JACK audio sound server
- --enable-libkvazaar HEVC video encoding
- --enable-libmp3lame MP3 audio encoding
- --enable-libopencore-amrnb AMR-NB audio encoding/decoding
- --enable-libopencore-amrwb AMR-WB audio decoding
- --enable-libopencv computer vision
- --enable-libopenh264 H.264 video encoding/decoding
- --enable-libopenjpeg JPEG 2000 image encoding/decoding
- --enable-libopus Opus audio encoding/decoding
- --enable-libpulse Pulseaudio sound server
- --enable-librtmp RTMP streaming
- --enable-libschroedinger Dirac video encoding/decoding
- --enable-libsnappy snappy compression
- --enable-libspeex Speex audio encoding/decoding
- --enable-libsrt Haivision SRT protocol
- --enable-libtheora Theora video encoding/decoding
- --enable-libtwolame MP2 audio encoding
- --enable-libvo-aacenc AAC audio encoding
- --enable-libvo-amrwbenc AMR-WB audio encoding
- --enable-libvorbis Vorbis audio encoding/decoding
- --enable-libvpx VP* video encoding/decoding
- --enable-libwavpack Wavpack audio encoding/decoding
- --enable-libwebp WebP image encoding/decoding
- --enable-libx264 H.264 video encoding
- --enable-libx265 HEVC video encoding
- --enable-libxavs Chinese AVS video encoding
- --enable-libxcb X window system protocol communication
- --enable-libxcb-shm X11 shm communication [auto]
- --enable-libxcb-xfixes X11 mouse rendering [auto]
- --enable-libxvid MPEG-4 ASP video encoding
- --enable-openssl crypto
- --enable-zlib compression [autodetect]
+ themselves, not all their features will necessarily be usable by FFmpeg.
+
+ --disable-alsa disable ALSA support [autodetect]
+ --disable-appkit disable Apple AppKit framework [autodetect]
+ --disable-avfoundation disable Apple AVFoundation framework [autodetect]
+ --enable-avisynth enable reading of AviSynth script files [no]
+ --disable-bzlib disable bzlib [autodetect]
+ --disable-coreimage disable Apple CoreImage framework [autodetect]
+ --enable-chromaprint enable audio fingerprinting with chromaprint [no]
+ --enable-frei0r enable frei0r video filtering [no]
+ --enable-gcrypt enable gcrypt, needed for rtmp(t)e support
+ if openssl, librtmp or gmp is not used [no]
+ --enable-gmp enable gmp, needed for rtmp(t)e support
+ if openssl or librtmp is not used [no]
+ --enable-gnutls enable gnutls, needed for https support
+ if openssl or libtls is not used [no]
+ --disable-iconv disable iconv [autodetect]
+ --enable-jni enable JNI support [no]
+ --enable-ladspa enable LADSPA audio filtering [no]
+ --enable-libaom enable AV1 video encoding/decoding via libaom [no]
+ --enable-libass enable libass subtitles rendering,
+ needed for subtitles and ass filter [no]
+ --enable-libbluray enable BluRay reading using libbluray [no]
+ --enable-libbs2b enable bs2b DSP library [no]
+ --enable-libcaca enable textual display using libcaca [no]
+ --enable-libcelt enable CELT decoding via libcelt [no]
+ --enable-libcdio enable audio CD grabbing with libcdio [no]
+ --enable-libcodec2 enable codec2 en/decoding using libcodec2 [no]
+ --enable-libdc1394 enable IIDC-1394 grabbing using libdc1394
+ and libraw1394 [no]
+ --enable-libfdk-aac enable AAC de/encoding via libfdk-aac [no]
+ --enable-libflite enable flite (voice synthesis) support via libflite [no]
+ --enable-libfontconfig enable libfontconfig, useful for drawtext filter [no]
+ --enable-libfreetype enable libfreetype, needed for drawtext filter [no]
+ --enable-libfribidi enable libfribidi, improves drawtext filter [no]
+ --enable-libgme enable Game Music Emu via libgme [no]
+ --enable-libgsm enable GSM de/encoding via libgsm [no]
+ --enable-libiec61883 enable iec61883 via libiec61883 [no]
+ --enable-libilbc enable iLBC de/encoding via libilbc [no]
+ --enable-libjack enable JACK audio sound server [no]
+ --enable-libkvazaar enable HEVC encoding via libkvazaar [no]
+ --enable-libmodplug enable ModPlug via libmodplug [no]
+ --enable-libmp3lame enable MP3 encoding via libmp3lame [no]
+ --enable-libopencore-amrnb enable AMR-NB de/encoding via libopencore-amrnb [no]
+ --enable-libopencore-amrwb enable AMR-WB decoding via libopencore-amrwb [no]
+ --enable-libopencv enable video filtering via libopencv [no]
+ --enable-libopenh264 enable H.264 encoding via OpenH264 [no]
+ --enable-libopenjpeg enable JPEG 2000 de/encoding via OpenJPEG [no]
+ --enable-libopenmpt enable decoding tracked files via libopenmpt [no]
+ --enable-libopus enable Opus de/encoding via libopus [no]
+ --enable-libpulse enable Pulseaudio input via libpulse [no]
+ --enable-librsvg enable SVG rasterization via librsvg [no]
+ --enable-librubberband enable rubberband needed for rubberband filter [no]
+ --enable-librtmp enable RTMP[E] support via librtmp [no]
+ --enable-libshine enable fixed-point MP3 encoding via libshine [no]
+ --enable-libsmbclient enable Samba protocol via libsmbclient [no]
+ --enable-libsnappy enable Snappy compression, needed for hap encoding [no]
+ --enable-libsoxr enable Include libsoxr resampling [no]
+ --enable-libspeex enable Speex de/encoding via libspeex [no]
++ --enable-libsrt enable Haivision SRT protocol via libsrt [no]
+ --enable-libssh enable SFTP protocol via libssh [no]
+ --enable-libtesseract enable Tesseract, needed for ocr filter [no]
+ --enable-libtheora enable Theora encoding via libtheora [no]
+ --enable-libtls enable LibreSSL (via libtls), needed for https support
+ if openssl or gnutls is not used [no]
+ --enable-libtwolame enable MP2 encoding via libtwolame [no]
+ --enable-libv4l2 enable libv4l2/v4l-utils [no]
+ --enable-libvidstab enable video stabilization using vid.stab [no]
+ --enable-libvmaf enable vmaf filter via libvmaf [no]
+ --enable-libvo-amrwbenc enable AMR-WB encoding via libvo-amrwbenc [no]
+ --enable-libvorbis enable Vorbis en/decoding via libvorbis,
+ native implementation exists [no]
+ --enable-libvpx enable VP8 and VP9 de/encoding via libvpx [no]
+ --enable-libwavpack enable wavpack encoding via libwavpack [no]
+ --enable-libwebp enable WebP encoding via libwebp [no]
+ --enable-libx264 enable H.264 encoding via x264 [no]
+ --enable-libx265 enable HEVC encoding via x265 [no]
+ --enable-libxavs enable AVS encoding via xavs [no]
+ --enable-libxcb enable X11 grabbing using XCB [autodetect]
+ --enable-libxcb-shm enable X11 grabbing shm communication [autodetect]
+ --enable-libxcb-xfixes enable X11 grabbing mouse rendering [autodetect]
+ --enable-libxcb-shape enable X11 grabbing shape rendering [autodetect]
+ --enable-libxvid enable Xvid encoding via xvidcore,
+ native MPEG-4/Xvid encoder exists [no]
+ --enable-libxml2 enable XML parsing using the C library libxml2 [no]
+ --enable-libzimg enable z.lib, needed for zscale filter [no]
+ --enable-libzmq enable message passing via libzmq [no]
+ --enable-libzvbi enable teletext support via libzvbi [no]
+ --enable-lv2 enable LV2 audio filtering [no]
+ --disable-lzma disable lzma [autodetect]
+ --enable-decklink enable Blackmagic DeckLink I/O support [no]
+ --enable-libndi_newtek enable Newteck NDI I/O support [no]
+ --enable-mediacodec enable Android MediaCodec support [no]
+ --enable-libmysofa enable libmysofa, needed for sofalizer filter [no]
+ --enable-openal enable OpenAL 1.1 capture support [no]
+ --enable-opencl enable OpenCL processing [no]
+ --enable-opengl enable OpenGL rendering [no]
+ --enable-openssl enable openssl, needed for https support
+ if gnutls or libtls is not used [no]
+ --disable-sndio disable sndio support [autodetect]
+ --disable-schannel disable SChannel SSP, needed for TLS support on
+ Windows if openssl and gnutls are not used [autodetect]
+ --disable-sdl2 disable sdl2 [autodetect]
+ --disable-securetransport disable Secure Transport, needed for TLS support
+ on OSX if openssl and gnutls are not used [autodetect]
+ --disable-xlib disable xlib [autodetect]
+ --disable-zlib disable zlib [autodetect]
The following libraries provide various hardware acceleration features:
- --enable-amf AMF video encoding code [auto]
- --enable-cuda Nvidia CUDA (dynamically linked)
- --enable-cuvid Nvidia CUVID video decode acceleration
- --enable-d3d11va Microsoft Direct3D 11 video acceleration [auto]
- --enable-dxva2 Microsoft DirectX 9 video acceleration [auto]
- --enable-libmfx Intel MediaSDK (AKA Quick Sync Video)
- --enable-libnpp Nvidia CUDA processing
- --enable-mmal Broadcom Multi-Media Abstraction Layer (Raspberry Pi)
- --enable-nvenc Nvidia video encoding
- --enable-omx OpenMAX IL
- --enable-omx-rpi OpenMAX IL for Raspberry Pi
- --enable-vaapi Video Acceleration API (mainly Unix/Intel)
- --enable-vda Apple Video Decode Acceleration [auto]
- --enable-vdpau Nvidia Video Decode and Presentation API for Unix [auto]
+ --disable-amf disable AMF video encoding code [autodetect]
+ --disable-audiotoolbox disable Apple AudioToolbox code [autodetect]
+ --enable-cuda-sdk enable CUDA features that require the CUDA SDK [no]
+ --disable-cuvid disable Nvidia CUVID support [autodetect]
+ --disable-d3d11va disable Microsoft Direct3D 11 video acceleration code [autodetect]
+ --disable-dxva2 disable Microsoft DirectX 9 video acceleration code [autodetect]
+ --disable-ffnvcodec disable dynamically linked Nvidia code [autodetect]
+ --enable-libdrm enable DRM code (Linux) [no]
+ --enable-libmfx enable Intel MediaSDK (AKA Quick Sync Video) code via libmfx [no]
+ --enable-libnpp enable Nvidia Performance Primitives-based code [no]
+ --enable-mmal enable Broadcom Multi-Media Abstraction Layer (Raspberry Pi) via MMAL [no]
+ --disable-nvdec disable Nvidia video decoding acceleration (via hwaccel) [autodetect]
+ --disable-nvenc disable Nvidia video encoding code [autodetect]
+ --enable-omx enable OpenMAX IL code [no]
+ --enable-omx-rpi enable OpenMAX IL code for Raspberry Pi [no]
+ --enable-rkmpp enable Rockchip Media Process Platform code [no]
+ --disable-v4l2-m2m disable V4L2 mem2mem code [autodetect]
+ --disable-vaapi disable Video Acceleration API (mainly Unix/Intel) code [autodetect]
+ --disable-vdpau disable Nvidia Video Decode and Presentation API for Unix code [autodetect]
+ --disable-videotoolbox disable VideoToolbox code [autodetect]
Toolchain options:
--arch=ARCH select architecture [$arch]
@@@ -1695,21 -1369,15 +1696,22 @@@ EXTERNAL_LIBRARY_LIST=
libopencv
libopenh264
libopenjpeg
+ libopenmpt
libopus
libpulse
+ librsvg
librtmp
- libschroedinger
+ libshine
+ libsmbclient
libsnappy
+ libsoxr
libspeex
+ libsrt
+ libssh
+ libtesseract
libtheora
libtwolame
+ libv4l2
libvorbis
libvpx
libwavpack
@@@ -3241,11 -2525,10 +3243,13 @@@ librtmpe_protocol_deps="librtmp
librtmps_protocol_deps="librtmp"
librtmpt_protocol_deps="librtmp"
librtmpte_protocol_deps="librtmp"
+libsmbclient_protocol_deps="libsmbclient gplv3"
+libssh_protocol_deps="libssh"
+libtls_conflict="openssl gnutls"
mmsh_protocol_select="http_protocol"
mmst_protocol_select="network"
+ libsrt_protocol_deps="libsrt"
+ libsrt_protocol_select="network"
rtmp_protocol_conflict="librtmp_protocol"
rtmp_protocol_select="tcp_protocol"
rtmp_protocol_suggest="zlib"
@@@ -5934,137 -4642,63 +5938,138 @@@ for func in $MATH_FUNCS; d
eval check_mathfunc $func \${${func}_args:-1} $libm_extralibs
done
+for func in $COMPLEX_FUNCS; do
+ eval check_complexfunc $func \${${func}_args:-1}
+done
+
# these are off by default, so fail if requested and not available
-enabled amf && require_cpp_condition AMF/core/Version.h "(AMF_VERSION_MAJOR << 48 | AMF_VERSION_MINOR << 32 | AMF_VERSION_RELEASE << 16 | AMF_VERSION_BUILD_NUM) >= 0x0001000400040001"
-enabled avisynth && require_header avisynth/avisynth_c.h
-enabled avxsynth && require_header avxsynth/avxsynth_c.h
-enabled cuda && require cuda cuda.h cuInit -lcuda
-enabled cuvid && require cuvid cuviddec.h cuvidCreateDecoder -lnvcuvid
+enabled cuda_sdk && require cuda_sdk cuda.h cuCtxCreate -lcuda
+enabled chromaprint && require chromaprint chromaprint.h chromaprint_get_version -lchromaprint
+enabled decklink && { require_header DeckLinkAPI.h &&
+ { test_cpp_condition DeckLinkAPIVersion.h "BLACKMAGIC_DECKLINK_API_VERSION >= 0x0a060100" || die "ERROR: Decklink API version must be >= 10.6.1."; } }
+enabled libndi_newtek && require_header Processing.NDI.Lib.h
enabled frei0r && require_header frei0r.h
-enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init &&
- check_lib gmp gmp.h mpz_export -lgmp
+enabled gmp && require gmp gmp.h mpz_export -lgmp
+enabled gnutls && require_pkg_config gnutls gnutls gnutls/gnutls.h gnutls_global_init
+enabled jni && { [ $target_os = "android" ] && check_header jni.h && enabled pthreads || die "ERROR: jni not found"; }
+enabled ladspa && require_header ladspa.h
enabled libaom && require_pkg_config libaom "aom >= 0.1.0" aom/aom_codec.h aom_codec_version
+enabled lv2 && require_pkg_config lv2 lilv-0 "lilv-0/lilv/lilv.h" lilv_world_new
+enabled libiec61883 && require libiec61883 libiec61883/iec61883.h iec61883_cmp_connect -lraw1394 -lavc1394 -lrom1394 -liec61883
+enabled libass && require_pkg_config libass libass ass/ass.h ass_library_init
+enabled libbluray && require_pkg_config libbluray libbluray libbluray/bluray.h bd_open
enabled libbs2b && require_pkg_config libbs2b libbs2b bs2b.h bs2b_open
+enabled libcelt && require libcelt celt/celt.h celt_decode -lcelt0 &&
+ { check_lib libcelt celt/celt.h celt_decoder_create_custom -lcelt0 ||
+ die "ERROR: libcelt must be installed and version must be >= 0.11.0."; }
+enabled libcaca && require_pkg_config libcaca caca caca.h caca_create_canvas
+enabled libcodec2 && require libcodec2 codec2/codec2.h codec2_create -lcodec2
enabled libdc1394 && require_pkg_config libdc1394 libdc1394-2 dc1394/dc1394.h dc1394_new
-enabled libdcadec && require libdcadec libdcadec/dca_context.h dcadec_context_create -ldcadec
-enabled libfaac && require libfaac "stdint.h faac.h" faacEncGetVersion -lfaac
-enabled libfdk_aac && require_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen
+enabled libdrm && require_pkg_config libdrm libdrm xf86drm.h drmGetVersion
+enabled libfdk_aac && { check_pkg_config libfdk_aac fdk-aac "fdk-aac/aacenc_lib.h" aacEncOpen ||
+ { require libfdk_aac fdk-aac/aacenc_lib.h aacEncOpen -lfdk-aac &&
+ warn "using libfdk without pkg-config"; } }
+flite_extralibs="-lflite_cmu_time_awb -lflite_cmu_us_awb -lflite_cmu_us_kal -lflite_cmu_us_kal16 -lflite_cmu_us_rms -lflite_cmu_us_slt -lflite_usenglish -lflite_cmulex -lflite"
+enabled libflite && require libflite "flite/flite.h" flite_init $flite_extralibs
+enabled fontconfig && enable libfontconfig
enabled libfontconfig && require_pkg_config libfontconfig fontconfig "fontconfig/fontconfig.h" FcInit
enabled libfreetype && require_pkg_config libfreetype freetype2 "ft2build.h FT_FREETYPE_H" FT_Init_FreeType
-enabled libgsm && require libgsm gsm.h gsm_create -lgsm
-enabled libhdcd && require_pkg_config libhdcd libhdcd "hdcd/hdcd_simple.h" hdcd_new
-enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc
+enabled libfribidi && require_pkg_config libfribidi fribidi fribidi.h fribidi_version_info
+enabled libgme && { check_pkg_config libgme libgme gme/gme.h gme_new_emu ||
+ require libgme gme/gme.h gme_new_emu -lgme -lstdc++; }
+enabled libgsm && { for gsm_hdr in "gsm.h" "gsm/gsm.h"; do
+ check_lib libgsm "${gsm_hdr}" gsm_create -lgsm && break;
+ done || die "ERROR: libgsm not found"; }
+enabled libilbc && require libilbc ilbc.h WebRtcIlbcfix_InitDecode -lilbc $pthreads_extralibs
enabled libkvazaar && require_pkg_config libkvazaar "kvazaar >= 0.8.1" kvazaar.h kvz_api_get
-enabled libmfx && require_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit
-enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame
-enabled libnpp && require libnpp npp.h nppGetLibVersion -lnppi -lnppc
+# While it may appear that require is being used as a pkg-config
+# fallback for libmfx, it is actually being used to detect a different
+# installation route altogether. If libmfx is installed via the Intel
+# Media SDK or Intel Media Server Studio, these don't come with
+# pkg-config support. Instead, users should make sure that the build
+# can find the libraries and headers through other means.
+enabled libmfx && { check_pkg_config libmfx libmfx "mfx/mfxvideo.h" MFXInit ||
+ { require libmfx "mfx/mfxvideo.h" MFXInit "-llibmfx $advapi32_extralibs" && warn "using libmfx without pkg-config"; } }
+enabled libmodplug && require_pkg_config libmodplug libmodplug libmodplug/modplug.h ModPlug_Load
+enabled libmp3lame && require "libmp3lame >= 3.98.3" lame/lame.h lame_set_VBR_quality -lmp3lame $libm_extralibs
+enabled libmysofa && require libmysofa "mysofa.h" mysofa_load -lmysofa $zlib_extralibs
+enabled libnpp && { check_lib libnpp npp.h nppGetLibVersion -lnppig -lnppicc -lnppc ||
+ check_lib libnpp npp.h nppGetLibVersion -lnppi -lnppc ||
+ die "ERROR: libnpp not found"; }
enabled libopencore_amrnb && require libopencore_amrnb opencore-amrnb/interf_dec.h Decoder_Interface_init -lopencore-amrnb
enabled libopencore_amrwb && require libopencore_amrwb opencore-amrwb/dec_if.h D_IF_init -lopencore-amrwb
-enabled libopencv && require_pkg_config libopencv opencv opencv/cv.h cvCreateImageHeader
+enabled libopencv && { check_header opencv2/core/core_c.h &&
+ { check_pkg_config libopencv opencv opencv2/core/core_c.h cvCreateImageHeader ||
+ require libopencv opencv2/core/core_c.h cvCreateImageHeader -lopencv_core -lopencv_imgproc; } ||
+ require_pkg_config libopencv opencv opencv/cxcore.h cvCreateImageHeader; }
enabled libopenh264 && require_pkg_config libopenh264 openh264 wels/codec_api.h WelsGetCodecVersion
-enabled libopenjpeg && { check_lib libopenjpeg openjpeg.h opj_version -lopenjpeg -DOPJ_STATIC ||
- 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 libopenjpeg && { check_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version ||
+ { require_pkg_config libopenjpeg "libopenjp2 >= 2.1.0" openjpeg.h opj_version -DOPJ_STATIC && add_cppflags -DOPJ_STATIC; } }
+enabled libopenmpt && require_pkg_config libopenmpt "libopenmpt >= 0.2.6557" libopenmpt/libopenmpt.h openmpt_module_create -lstdc++ && append libopenmpt_extralibs "-lstdc++"
+enabled libopus && {
+ enabled libopus_decoder && {
+ require_pkg_config libopus opus opus_multistream.h opus_multistream_decoder_create
+ }
+ enabled libopus_encoder && {
+ require_pkg_config libopus opus opus_multistream.h opus_multistream_surround_encoder_create
+ }
+}
+enabled libpulse && require_pkg_config libpulse libpulse pulse/pulseaudio.h pa_context_new
+enabled librsvg && require_pkg_config librsvg librsvg-2.0 librsvg-2.0/librsvg/rsvg.h rsvg_handle_render_cairo
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
+enabled librubberband && require_pkg_config librubberband "rubberband >= 1.8.1" rubberband/rubberband-c.h rubberband_new -lstdc++ && append librubberband_extralibs "-lstdc++"
+enabled libshine && require_pkg_config libshine shine shine/layer3.h shine_encode_buffer
+enabled libsmbclient && { check_pkg_config libsmbclient smbclient libsmbclient.h smbc_init ||
+ require libsmbclient libsmbclient.h smbc_init -lsmbclient; }
+enabled libsnappy && require libsnappy snappy-c.h snappy_compress -lsnappy -lstdc++
+enabled libsoxr && require libsoxr soxr.h soxr_create -lsoxr
+enabled libssh && require_pkg_config libssh libssh libssh/sftp.h sftp_init
enabled libspeex && require_pkg_config libspeex speex speex/speex.h speex_decoder_init
+ enabled libsrt && require_pkg_config libsrt "srt >= 1.2.0" srt/srt.h srt_socket
+enabled libtesseract && require_pkg_config libtesseract tesseract tesseract/capi.h TessBaseAPICreate
enabled libtheora && require libtheora theora/theoraenc.h th_info_init -ltheoraenc -ltheoradec -logg
-enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame
-enabled libvo_aacenc && require libvo_aacenc vo-aacenc/voAAC.h voGetAACEncAPI -lvo-aacenc
+enabled libtls && require_pkg_config libtls libtls tls.h tls_configure
+enabled libtwolame && require libtwolame twolame.h twolame_init -ltwolame &&
+ { check_lib libtwolame twolame.h twolame_encode_buffer_float32_interleaved -ltwolame ||
+ die "ERROR: libtwolame must be installed and version must be >= 0.3.10"; }
+enabled libv4l2 && require_pkg_config libv4l2 libv4l2 libv4l2.h v4l2_ioctl
+enabled libvidstab && require_pkg_config libvidstab "vidstab >= 0.98" vid.stab/libvidstab.h vsMotionDetectInit
+enabled libvmaf && require_pkg_config libvmaf "libvmaf >= 0.6.2" libvmaf.h compute_vmaf
enabled libvo_amrwbenc && require libvo_amrwbenc vo-amrwbenc/enc_if.h E_IF_init -lvo-amrwbenc
-enabled libvorbis && require libvorbis vorbis/vorbisenc.h vorbis_info_init -lvorbisenc -lvorbis -logg
-enabled libvpx && require_pkg_config libvpx "vpx >= 1.3.0" vpx/vpx_codec.h vpx_codec_version &&
- { enabled libvpx_vp8_decoder &&
- check_pkg_config libvpx_vp8_decoder vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx
- enabled libvpx_vp8_encoder &&
- check_pkg_config libvpx_vp8_encoder vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx
- enabled libvpx_vp9_decoder &&
- check_pkg_config libvpx_vp9_decoder vpx "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx
- enabled libvpx_vp9_encoder &&
- check_pkg_config libvpx_vp9_encoder vpx "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx
- disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder &&
- die "libvpx enabled but no supported decoders/encoders found"
- }
+enabled libvorbis && require_pkg_config libvorbis vorbis vorbis/codec.h vorbis_info_init &&
+ require_pkg_config libvorbisenc vorbisenc vorbis/vorbisenc.h vorbis_encode_init
+
+enabled libvpx && {
+ enabled libvpx_vp8_decoder && {
+ check_pkg_config libvpx_vp8_decoder "vpx >= 1.4.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp8_dx ||
+ check_lib libvpx_vp8_decoder "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_dec_init_ver VPX_IMG_FMT_HIGHBITDEPTH" -lvpx ||
+ die "ERROR: libvpx decoder version must be >=1.4.0";
+ }
+ enabled libvpx_vp8_encoder && {
+ check_pkg_config libvpx_vp8_encoder "vpx >= 1.4.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp8_cx ||
+ check_lib libvpx_vp8_encoder "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_enc_init_ver VPX_IMG_FMT_HIGHBITDEPTH" -lvpx ||
+ die "ERROR: libvpx encoder version must be >=1.4.0";
+ }
+ enabled libvpx_vp9_decoder && {
+ check_pkg_config libvpx_vp9_decoder "vpx >= 1.4.0" "vpx/vpx_decoder.h vpx/vp8dx.h" vpx_codec_vp9_dx ||
+ check_lib libvpx_vp9_decoder "vpx/vpx_decoder.h vpx/vp8dx.h" "vpx_codec_vp9_dx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs"
+ }
+ enabled libvpx_vp9_encoder && {
+ check_pkg_config libvpx_vp9_encoder "vpx >= 1.4.0" "vpx/vpx_encoder.h vpx/vp8cx.h" vpx_codec_vp9_cx ||
+ check_lib libvpx_vp9_encoder "vpx/vpx_encoder.h vpx/vp8cx.h" "vpx_codec_vp9_cx VPX_IMG_FMT_HIGHBITDEPTH" "-lvpx $libm_extralibs"
+ }
+ if disabled_all libvpx_vp8_decoder libvpx_vp9_decoder libvpx_vp8_encoder libvpx_vp9_encoder; then
+ die "libvpx enabled but no supported decoders found"
+ fi
+}
+
enabled libwavpack && require libwavpack wavpack/wavpack.h WavpackOpenFileOutput -lwavpack
-enabled libwebp && require_pkg_config libwebp libwebp webp/encode.h WebPGetEncoderVersion
-enabled libx264 && require_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode &&
+enabled libwebp && {
+ enabled libwebp_encoder && require_pkg_config libwebp "libwebp >= 0.2.0" webp/encode.h WebPGetEncoderVersion
+ enabled libwebp_anim_encoder && check_pkg_config libwebp_anim_encoder "libwebpmux >= 0.4.0" webp/mux.h WebPAnimEncoderOptionsInit; }
+enabled libx264 && { check_pkg_config libx264 x264 "stdint.h x264.h" x264_encoder_encode ||
+ { require libx264 "stdint.h x264.h" x264_encoder_encode "-lx264 $pthreads_extralibs $libm_extralibs" &&
+ warn "using libx264 without pkg-config"; } } &&
require_cpp_condition x264.h "X264_BUILD >= 118" &&
check_cpp_condition libx262 x264.h "X264_MPEG2"
enabled libx265 && require_pkg_config libx265 x265 x265.h x265_api_get &&
diff --cc doc/protocols.texi
index c24dc74505,e2d06a0675..e19504d073
--- a/doc/protocols.texi
+++ b/doc/protocols.texi
@@@ -1134,94 -652,149 +1134,234 @@@ ffplay sap:/
To play back the first stream announced on one the default IPv6 SAP multicast address:
@example
-avplay sap://[ff0e::2:7ffe]
+ffplay sap://[ff0e::2:7ffe]
+ at end example
+
+ at section sctp
+
+Stream Control Transmission Protocol.
+
+The accepted URL syntax is:
+ at example
+sctp://@var{host}:@var{port}[?@var{options}]
@end example
+The protocol accepts the following options:
+ at table @option
+ at item listen
+If set to any value, listen for an incoming connection. Outgoing connection is done by default.
+
+ at item max_streams
+Set the maximum number of streams. By default no limit is set.
+ at end table
+
+ @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 '- at 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 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}.
+
+ at section srtp
+
+Secure Real-time Transport Protocol.
+
+The accepted options are:
+ at table @option
+ at item srtp_in_suite
+ at item srtp_out_suite
+Select input and output encoding suites.
+
+Supported values:
+ at table @samp
+ at item AES_CM_128_HMAC_SHA1_80
+ at item SRTP_AES128_CM_HMAC_SHA1_80
+ at item AES_CM_128_HMAC_SHA1_32
+ at item SRTP_AES128_CM_HMAC_SHA1_32
+ at end table
+
+ at item srtp_in_params
+ at item srtp_out_params
+Set input and output encoding parameters, which are expressed by a
+base64-encoded representation of a binary block. The first 16 bytes of
+this binary block are used as master key, the following 14 bytes are
+used as master salt.
+ at end table
+
+ at section subfile
+
+Virtually extract a segment of a file or another stream.
+The underlying stream must be seekable.
+
+Accepted options:
+ at table @option
+ at item start
+Start offset of the extracted segment, in bytes.
+ at item end
+End offset of the extracted segment, in bytes.
+If set to 0, extract till end of file.
+ at end table
+
+Examples:
+
+Extract a chapter from a DVD VOB file (start and end sectors obtained
+externally and multiplied by 2048):
+ at example
+subfile,,start,153391104,end,268142592,,:/media/dvd/VIDEO_TS/VTS_08_1.VOB
+ at end example
+
+Play an AVI file directly from a TAR archive:
+ at example
+subfile,,start,183241728,end,366490624,,:archive.tar
+ at end example
+
+Play a MPEG-TS file from start offset till end:
+ at example
+subfile,,start,32815239,end,0,,:video.ts
+ at end example
+
+ at section tee
+
+Writes the output to multiple protocols. The individual outputs are separated
+by |
+
+ at example
+tee:file://path/to/local/this.avi|file://path/to/local/that.avi
+ at end example
+
@section tcp
Transmission Control Protocol.
diff --cc libavformat/Makefile
index 39ec68c28b,96085d20c6..af0823a7db
--- a/libavformat/Makefile
+++ b/libavformat/Makefile
@@@ -557,26 -379,12 +557,27 @@@ OBJS-$(CONFIG_YUV4MPEGPIPE_MUXER
# external libraries
OBJS-$(CONFIG_AVISYNTH_DEMUXER) += avisynth.o
-OBJS-$(CONFIG_LIBRTMP) += librtmp.o
+OBJS-$(CONFIG_CHROMAPRINT_MUXER) += chromaprint.o
+OBJS-$(CONFIG_LIBGME_DEMUXER) += libgme.o
+OBJS-$(CONFIG_LIBMODPLUG_DEMUXER) += libmodplug.o
+OBJS-$(CONFIG_LIBOPENMPT_DEMUXER) += libopenmpt.o
+OBJS-$(CONFIG_LIBRTMP_PROTOCOL) += librtmp.o
+OBJS-$(CONFIG_LIBRTMPE_PROTOCOL) += librtmp.o
+OBJS-$(CONFIG_LIBRTMPS_PROTOCOL) += librtmp.o
+OBJS-$(CONFIG_LIBRTMPT_PROTOCOL) += librtmp.o
+OBJS-$(CONFIG_LIBRTMPTE_PROTOCOL) += librtmp.o
++OBJS-$(CONFIG_LIBSRT_PROTOCOL) += libsrt.o
+OBJS-$(CONFIG_LIBSSH_PROTOCOL) += libssh.o
+OBJS-$(CONFIG_LIBSMBCLIENT_PROTOCOL) += libsmbclient.o
# protocols I/O
+OBJS-$(CONFIG_ASYNC_PROTOCOL) += async.o
OBJS-$(CONFIG_APPLEHTTP_PROTOCOL) += hlsproto.o
+OBJS-$(CONFIG_BLURAY_PROTOCOL) += bluray.o
+OBJS-$(CONFIG_CACHE_PROTOCOL) += cache.o
OBJS-$(CONFIG_CONCAT_PROTOCOL) += concat.o
OBJS-$(CONFIG_CRYPTO_PROTOCOL) += crypto.o
+OBJS-$(CONFIG_DATA_PROTOCOL) += data_uri.o
OBJS-$(CONFIG_FFRTMPCRYPT_PROTOCOL) += rtmpcrypt.o rtmpdigest.o rtmpdh.o
OBJS-$(CONFIG_FFRTMPHTTP_PROTOCOL) += rtmphttp.o
OBJS-$(CONFIG_FILE_PROTOCOL) += file.o
diff --cc libavformat/libsrt.c
index 0000000000,3e50dab64f..0f9529d263
mode 000000,100644..100644
--- a/libavformat/libsrt.c
+++ b/libavformat/libsrt.c
@@@ -1,0 -1,546 +1,546 @@@
+ /*
- * This file is part of Libav.
++ * This file is part of FFmpeg.
+ *
- * Libav is free software; you can redistribute it and/or
++ * FFmpeg 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,
++ * FFmpeg 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
++ * License along with FFmpeg; 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 <srt/srt.h>
+
+ #include "libavutil/avassert.h"
+ #include "libavutil/opt.h"
+ #include "libavutil/parseutils.h"
+ #include "libavutil/time.h"
+
+ #include "avformat.h"
+ #include "internal.h"
+ #include "network.h"
+ #include "os_support.h"
+ #include "url.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 libsrt_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 libsrt_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 libsrt_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 libsrt_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 libsrt_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 = libsrt_neterrno(h);
+ } else {
+ ret = 0;
+ }
+ if (srt_epoll_remove_usock(eid, fd) < 0)
+ return libsrt_neterrno(h);
+ return ret;
+ }
+
+ /* TODO de-duplicate code from ff_network_wait_fd_timeout() */
+
+ static int libsrt_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 = libsrt_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 libsrt_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 libsrt_neterrno(h);
+
+ ret = srt_listen(fd, 1);
+ if (ret)
+ return libsrt_neterrno(h);
+
+ while ((ret = libsrt_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 libsrt_neterrno(h);
+ if (libsrt_socket_nonblock(ret, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");
+
+ return ret;
+ }
+
+ static int libsrt_listen_connect(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout, URLContext *h, int will_try_next)
+ {
+ int ret;
+
+ if (libsrt_socket_nonblock(fd, 1) < 0)
+ av_log(h, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
+
+ while ((ret = srt_connect(fd, addr, addrlen))) {
+ ret = libsrt_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 = libsrt_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 libsrt_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 libsrt_set_options_post(URLContext *h, int fd)
+ {
+ SRTContext *s = h->priv_data;
+
+ if ((s->inputbw >= 0 && libsrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) ||
+ (s->oheadbw >= 0 && libsrt_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 libsrt_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 && libsrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) ||
+ (s->maxbw >= 0 && libsrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) ||
+ (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
+ (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", &s->passphrase, sizeof(s->passphrase)) < 0) ||
+ (s->mss >= 0 && libsrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MMS", &s->mss, sizeof(s->mss)) < 0) ||
+ (s->ffs >= 0 && libsrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) ||
+ (s->ipttl >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_UPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) ||
+ (s->iptos >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) ||
+ (tsbpddelay >= 0 && libsrt_setsockopt(h, fd, SRTO_TSBPDDELAY, "SRTO_TSBPDELAY", &tsbpddelay, sizeof(tsbpddelay)) < 0) ||
+ (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) ||
+ (s->nakreport >= 0 && libsrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) ||
+ (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 )) {
+ return AVERROR(EIO);
+ }
+ return 0;
+ }
+
+
+ static int libsrt_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 libsrt_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 = libsrt_neterrno(h);
+ goto fail;
+ }
+
+ if ((ret = libsrt_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 = libsrt_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 = libsrt_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 = libsrt_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 libsrt_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 libsrt_setup(h, uri, flags);
+ }
+
+ static int libsrt_read(URLContext *h, uint8_t *buf, int size)
+ {
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = libsrt_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 = libsrt_neterrno(h);
+ }
+
+ return ret;
+ }
+
+ static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
+ {
+ SRTContext *s = h->priv_data;
+ int ret;
+
+ if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
+ ret = libsrt_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 = libsrt_neterrno(h);
+ }
+
+ return ret;
+ }
+
+ static int libsrt_close(URLContext *h)
+ {
+ SRTContext *s = h->priv_data;
+
+ srt_close(s->fd);
+
+ srt_epoll_release(s->eid);
+
+ srt_cleanup();
+
+ return 0;
+ }
+
+ static int libsrt_get_file_handle(URLContext *h)
+ {
+ SRTContext *s = h->priv_data;
+ return s->fd;
+ }
+
+ static const AVClass libsrt_class = {
+ .class_name = "libsrt",
+ .item_name = av_default_item_name,
+ .option = libsrt_options,
+ .version = LIBAVUTIL_VERSION_INT,
+ };
+
+ const URLProtocol ff_libsrt_protocol = {
+ .name = "srt",
+ .url_open = libsrt_open,
+ .url_read = libsrt_read,
+ .url_write = libsrt_write,
+ .url_close = libsrt_close,
+ .url_get_file_handle = libsrt_get_file_handle,
+ .priv_data_size = sizeof(SRTContext),
+ .flags = URL_PROTOCOL_FLAG_NETWORK,
+ .priv_data_class = &libsrt_class,
+ };
diff --cc libavformat/protocols.c
index 669d74d5a8,15b9ed736d..ad95659795
--- a/libavformat/protocols.c
+++ b/libavformat/protocols.c
@@@ -65,8 -56,7 +65,9 @@@ extern const URLProtocol ff_librtmpe_pr
extern const URLProtocol ff_librtmps_protocol;
extern const URLProtocol ff_librtmpt_protocol;
extern const URLProtocol ff_librtmpte_protocol;
+ extern const URLProtocol ff_libsrt_protocol;
+extern const URLProtocol ff_libssh_protocol;
+extern const URLProtocol ff_libsmbclient_protocol;
#include "libavformat/protocol_list.c"
More information about the ffmpeg-cvslog
mailing list