38 #ifndef SRT_LIVE_DEFAULT_PAYLOAD_SIZE 39 #define SRT_LIVE_DEFAULT_PAYLOAD_SIZE 1316 43 #ifndef SRT_LIVE_MAX_PAYLOAD_SIZE 44 #define SRT_LIVE_MAX_PAYLOAD_SIZE 1456 65 #if SRT_VERSION_VALUE >= 0x010302 66 int enforced_encryption;
95 #define D AV_OPT_FLAG_DECODING_PARAM 96 #define E AV_OPT_FLAG_ENCODING_PARAM 97 #define OFFSET(x) offsetof(SRTContext, x) 107 {
"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 },
108 {
"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 },
110 #if SRT_VERSION_VALUE >= 0x010302 111 {
"enforced_encryption",
"Enforces that both connection parties have the same passphrase set",
OFFSET(enforced_encryption),
AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags =
D|
E },
112 {
"kmrefreshrate",
"The number of packets to be transmitted after which the encryption key is switched to a new key",
OFFSET(kmrefreshrate),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
113 {
"kmpreannounce",
"The interval between when a new encryption key is sent and when switchover occurs",
OFFSET(kmpreannounce),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
116 {
"ffs",
"Flight flag size (window size) (in bytes)",
OFFSET(
ffs),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
121 {
"latency",
"receiver delay (in microseconds) to absorb bursts of missed packet retransmissions",
OFFSET(
latency),
AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags =
D|
E },
128 {
"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" },
139 {
"transtype",
"The transmission type for the socket",
OFFSET(
transtype),
AV_OPT_TYPE_INT, { .i64 = SRTT_INVALID }, SRTT_LIVE, SRTT_INVALID, .flags =
D|
E,
"transtype" },
142 {
"linger",
"Number of seconds that the socket waits for unsent data when closing",
OFFSET(
linger),
AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags =
D|
E },
149 int err = srt_getlasterror(&os_errno);
150 if (err == SRT_EASYNCRCV || err == SRT_EASYNCSND)
158 int ret, blocking = enable ? 0 : 1;
160 ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &blocking,
sizeof(blocking));
163 return srt_setsockopt(socket, 0, SRTO_RCVSYN, &blocking,
sizeof(blocking));
168 int ret,
len = 1, errlen = 1;
169 int modes = SRT_EPOLL_ERR | (write ? SRT_EPOLL_OUT : SRT_EPOLL_IN);
173 if (srt_epoll_add_usock(eid, fd, &modes) < 0)
176 ret = srt_epoll_wait(eid, error, &errlen, ready, &len,
POLLING_TIME, 0, 0, 0, 0);
178 ret = srt_epoll_wait(eid, ready, &len, error, &errlen,
POLLING_TIME, 0, 0, 0, 0);
181 if (srt_getlasterror(
NULL) == SRT_ETIMEOUT)
186 ret = errlen ?
AVERROR(EIO) : 0;
188 if (srt_epoll_remove_usock(eid, fd) < 0)
198 int64_t wait_start = 0;
219 if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse,
sizeof(reuse))) {
222 ret = srt_bind(fd, addr, addrlen);
226 ret = srt_listen(fd, 1);
247 ret = srt_connect(fd, addr, addrlen);
255 "Connection to %s failed (%s), trying next address\n",
267 if (srt_setsockopt(fd, 0, optname, optval, optlen) < 0) {
268 av_log(h,
AV_LOG_ERROR,
"failed to set option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
276 if (srt_getsockopt(fd, 0, optname, optval, optlen) < 0) {
277 av_log(h,
AV_LOG_ERROR,
"failed to get option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
315 #
if SRT_VERSION_VALUE >= 0x010302
317 (s->enforced_encryption >= 0 &&
libsrt_setsockopt(h, fd, SRTO_STRICTENC,
"SRTO_STRICTENC", &s->enforced_encryption,
sizeof(s->enforced_encryption)) < 0) ||
318 (s->kmrefreshrate >= 0 &&
libsrt_setsockopt(h, fd, SRTO_KMREFRESHRATE,
"SRTO_KMREFRESHRATE", &s->kmrefreshrate,
sizeof(s->kmrefreshrate)) < 0) ||
319 (s->kmpreannounce >= 0 &&
libsrt_setsockopt(h, fd, SRTO_KMPREANNOUNCE,
"SRTO_KMPREANNOUNCE", &s->kmpreannounce,
sizeof(s->kmpreannounce)) < 0) ||
330 (connect_timeout >= 0 &&
libsrt_setsockopt(h, fd, SRTO_CONNTIMEO,
"SRTO_CONNTIMEO", &connect_timeout,
sizeof(connect_timeout)) <0 ) ||
346 lin.l_onoff = lin.l_linger > 0 ? 1 : 0;
356 struct addrinfo hints = { 0 }, *ai, *cur_ai;
362 char hostname[1024],proto[1024],path[1024];
364 int64_t open_timeout = 0;
367 eid = srt_epoll_create();
373 &port, path,
sizeof(path), uri);
374 if (strcmp(proto,
"srt"))
376 if (port <= 0 || port >= 65536) {
380 p = strchr(uri,
'?');
394 snprintf(portstr,
sizeof(portstr),
"%d", port);
397 ret =
getaddrinfo(hostname[0] ? hostname :
NULL, portstr, &hints, &ai);
400 "Failed to resolve hostname %s: %s\n",
409 fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
437 ret = srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
443 open_timeout, h, !!cur_ai->ai_next)) < 0) {
456 int optlen =
sizeof(packet_size);
457 ret =
libsrt_getsockopt(h, fd, SRTO_PAYLOADSIZE,
"SRTO_PAYLOADSIZE", &packet_size, &optlen);
471 if (cur_ai->ai_next) {
473 cur_ai = cur_ai->ai_next;
493 if (srt_startup() < 0) {
498 p = strchr(uri,
'?');
510 #if SRT_VERSION_VALUE >= 0x010302 512 s->enforced_encryption = strtol(buf,
NULL, 10);
515 s->kmrefreshrate = strtol(buf,
NULL, 10);
518 s->kmpreannounce = strtol(buf,
NULL, 10);
522 s->
mss = strtol(buf,
NULL, 10);
525 s->
ffs = strtol(buf,
NULL, 10);
565 if (!strcmp(buf,
"caller")) {
567 }
else if (!strcmp(buf,
"listener")) {
569 }
else if (!strcmp(buf,
"rendezvous")) {
607 if (!strcmp(buf,
"live")) {
609 }
else if (!strcmp(buf,
"file")) {
638 ret = srt_recvmsg(s->
fd, buf, size);
657 ret = srt_sendmsg(s->
fd, buf, size, -1, 0);
671 srt_epoll_release(s->
eid);
700 .priv_data_class = &libsrt_class,
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
#define URL_PROTOCOL_FLAG_NETWORK
static int libsrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int64_t timeout)
static int libsrt_open(URLContext *h, const char *uri, int flags)
#define AV_LOG_WARNING
Something somehow does not look correct.
#define LIBAVUTIL_VERSION_INT
int is_streamed
true if streamed (no seek possible), default = false
AVIOInterruptCB interrupt_callback
static int libsrt_listen_connect(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, int64_t timeout, URLContext *h, int will_try_next)
const char * av_default_item_name(void *ptr)
Return the context name.
int64_t rw_timeout
maximum time to wait for (network) read/write operation completion, in mcs
#define AVIO_FLAG_WRITE
write-only
static void error(const char *err)
static int libsrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char *optnamestr, const void *optval, int optlen)
static int libsrt_socket_nonblock(int socket, int enable)
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
miscellaneous OS support macros and functions.
static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char *optnamestr, void *optval, int *optlen)
int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
Attempt to find a specific tag in a URL.
Callback for checking whether to abort blocking functions.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static const AVClass libsrt_class
static int libsrt_setup(URLContext *h, const char *uri, int flags)
const AVIOInterruptCB int_cb
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static int libsrt_set_options_post(URLContext *h, int fd)
simple assert() macros that are a bit more flexible than ISO C assert().
static int libsrt_network_wait_fd(URLContext *h, int eid, int fd, int write)
#define SRT_LIVE_MAX_PAYLOAD_SIZE
static int libsrt_read(URLContext *h, uint8_t *buf, int size)
static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
#define SRT_LIVE_DEFAULT_PAYLOAD_SIZE
static int libsrt_get_file_handle(URLContext *h)
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
static const AVOption libsrt_options[]
char * av_strdup(const char *s)
Duplicate a string.
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
const URLProtocol ff_libsrt_protocol
Describe the class of an AVClass context structure.
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
#define flags(name, subs,...)
char * filename
specified URL
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
static const SiprModeParam modes[MODE_COUNT]
static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
static int libsrt_close(URLContext *h)
int max_packet_size
if non zero, the stream is packetized with this max packet size
unbuffered private I/O API
mode
Use these values in ebur128_init (or'ed).
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
static int libsrt_set_options_pre(URLContext *h, int fd)
static int libsrt_neterrno(URLContext *h)