FFmpeg
libsrt.c
Go to the documentation of this file.
1 /*
2  * This file is part of FFmpeg.
3  *
4  * FFmpeg is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * FFmpeg is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with FFmpeg; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /**
20  * @file
21  * Haivision Open SRT (Secure Reliable Transport) protocol
22  */
23 
24 #include <srt/srt.h>
25 
26 #include "libavutil/avassert.h"
27 #include "libavutil/opt.h"
28 #include "libavutil/parseutils.h"
29 #include "libavutil/time.h"
30 
31 #include "avformat.h"
32 #include "internal.h"
33 #include "network.h"
34 #include "os_support.h"
35 #include "url.h"
36 
37 /* This is for MPEG-TS and it's a default SRTO_PAYLOADSIZE for SRTT_LIVE (8 TS packets) */
38 #ifndef SRT_LIVE_DEFAULT_PAYLOAD_SIZE
39 #define SRT_LIVE_DEFAULT_PAYLOAD_SIZE 1316
40 #endif
41 
42 /* This is the maximum payload size for Live mode, should you have a different payload type than MPEG-TS */
43 #ifndef SRT_LIVE_MAX_PAYLOAD_SIZE
44 #define SRT_LIVE_MAX_PAYLOAD_SIZE 1456
45 #endif
46 
47 enum SRTMode {
51 };
52 
53 typedef struct SRTContext {
54  const AVClass *class;
55  int fd;
56  int eid;
57  int64_t rw_timeout;
58  int64_t listen_timeout;
61 
62  int64_t maxbw;
63  int pbkeylen;
64  char *passphrase;
65 #if SRT_VERSION_VALUE >= 0x010302
66  int enforced_encryption;
67  int kmrefreshrate;
68  int kmpreannounce;
69 #endif
70  int mss;
71  int ffs;
72  int ipttl;
73  int iptos;
74  int64_t inputbw;
75  int oheadbw;
76  int64_t latency;
77  int tlpktdrop;
78  int nakreport;
79  int64_t connect_timeout;
81  int64_t rcvlatency;
82  int64_t peerlatency;
83  enum SRTMode mode;
84  int sndbuf;
85  int rcvbuf;
88  char *streamid;
89  char *smoother;
91  SRT_TRANSTYPE transtype;
92  int linger;
93 } SRTContext;
94 
95 #define D AV_OPT_FLAG_DECODING_PARAM
96 #define E AV_OPT_FLAG_ENCODING_PARAM
97 #define OFFSET(x) offsetof(SRTContext, x)
98 static const AVOption libsrt_options[] = {
99  { "timeout", "Timeout of socket I/O operations (in microseconds)", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
100  { "listen_timeout", "Connection awaiting timeout (in microseconds)" , OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
101  { "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 },
102  { "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 },
103  { "pkt_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, "payload_size" },
104  { "payload_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, "payload_size" },
105  { "ts_size", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_LIVE_DEFAULT_PAYLOAD_SIZE }, INT_MIN, INT_MAX, .flags = D|E, "payload_size" },
106  { "max_size", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_LIVE_MAX_PAYLOAD_SIZE }, INT_MIN, INT_MAX, .flags = D|E, "payload_size" },
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 },
109  { "passphrase", "Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto", OFFSET(passphrase), AV_OPT_TYPE_STRING, { .str = NULL }, .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 },
114 #endif
115  { "mss", "The Maximum Segment Size", OFFSET(mss), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1500, .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 },
117  { "ipttl", "IP Time To Live", OFFSET(ipttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
118  { "iptos", "IP Type of Service", OFFSET(iptos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
119  { "inputbw", "Estimated input stream rate", OFFSET(inputbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
120  { "oheadbw", "MaxBW ceiling based on % over input stream rate", OFFSET(oheadbw), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, .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 },
122  { "tsbpddelay", "deprecated, same effect as latency option", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
123  { "rcvlatency", "receive latency (in microseconds)", OFFSET(rcvlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
124  { "peerlatency", "peer latency (in microseconds)", OFFSET(peerlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
125  { "tlpktdrop", "Enable too-late pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
126  { "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
127  { "connect_timeout", "Connect timeout(in milliseconds). Caller default: 3000, rendezvous (x 10)", OFFSET(connect_timeout), 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" },
129  { "caller", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_CALLER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
130  { "listener", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_LISTENER }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
131  { "rendezvous", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_RENDEZVOUS }, INT_MIN, INT_MAX, .flags = D|E, "mode" },
132  { "sndbuf", "Send buffer size (in bytes)", OFFSET(sndbuf), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
133  { "rcvbuf", "Receive buffer size (in bytes)", OFFSET(rcvbuf), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
134  { "lossmaxttl", "Maximum possible packet reorder tolerance", OFFSET(lossmaxttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
135  { "minversion", "The minimum SRT version that is required from the peer", OFFSET(minversion), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
136  { "streamid", "A string of up to 512 characters that an Initiator can pass to a Responder", OFFSET(streamid), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
137  { "smoother", "The type of Smoother used for the transmission for that socket", OFFSET(smoother), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
138  { "messageapi", "Enable message API", OFFSET(messageapi), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
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" },
140  { "live", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRTT_LIVE }, INT_MIN, INT_MAX, .flags = D|E, "transtype" },
141  { "file", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRTT_FILE }, INT_MIN, INT_MAX, .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 },
143  { NULL }
144 };
145 
147 {
148  int os_errno;
149  int err = srt_getlasterror(&os_errno);
150  if (err == SRT_EASYNCRCV || err == SRT_EASYNCSND)
151  return AVERROR(EAGAIN);
152  av_log(h, AV_LOG_ERROR, "%s\n", srt_getlasterror_str());
153  return os_errno ? AVERROR(os_errno) : AVERROR_UNKNOWN;
154 }
155 
156 static int libsrt_socket_nonblock(int socket, int enable)
157 {
158  int ret, blocking = enable ? 0 : 1;
159  /* Setting SRTO_{SND,RCV}SYN options to 1 enable blocking mode, setting them to 0 enable non-blocking mode. */
160  ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &blocking, sizeof(blocking));
161  if (ret < 0)
162  return ret;
163  return srt_setsockopt(socket, 0, SRTO_RCVSYN, &blocking, sizeof(blocking));
164 }
165 
166 static int libsrt_epoll_create(URLContext *h, int fd, int write)
167 {
168  int modes = SRT_EPOLL_ERR | (write ? SRT_EPOLL_OUT : SRT_EPOLL_IN);
169  int eid = srt_epoll_create();
170  if (eid < 0)
171  return libsrt_neterrno(h);
172  if (srt_epoll_add_usock(eid, fd, &modes) < 0) {
173  srt_epoll_release(eid);
174  return libsrt_neterrno(h);
175  }
176  return eid;
177 }
178 
179 static int libsrt_network_wait_fd(URLContext *h, int eid, int write)
180 {
181  int ret, len = 1, errlen = 1;
182  SRTSOCKET ready[1];
183  SRTSOCKET error[1];
184 
185  if (write) {
186  ret = srt_epoll_wait(eid, error, &errlen, ready, &len, POLLING_TIME, 0, 0, 0, 0);
187  } else {
188  ret = srt_epoll_wait(eid, ready, &len, error, &errlen, POLLING_TIME, 0, 0, 0, 0);
189  }
190  if (ret < 0) {
191  if (srt_getlasterror(NULL) == SRT_ETIMEOUT)
192  ret = AVERROR(EAGAIN);
193  else
194  ret = libsrt_neterrno(h);
195  } else {
196  ret = errlen ? AVERROR(EIO) : 0;
197  }
198  return ret;
199 }
200 
201 /* TODO de-duplicate code from ff_network_wait_fd_timeout() */
202 
203 static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int write, int64_t timeout, AVIOInterruptCB *int_cb)
204 {
205  int ret;
206  int64_t wait_start = 0;
207 
208  while (1) {
210  return AVERROR_EXIT;
211  ret = libsrt_network_wait_fd(h, eid, write);
212  if (ret != AVERROR(EAGAIN))
213  return ret;
214  if (timeout > 0) {
215  if (!wait_start)
216  wait_start = av_gettime_relative();
217  else if (av_gettime_relative() - wait_start > timeout)
218  return AVERROR(ETIMEDOUT);
219  }
220  }
221 }
222 
223 static int libsrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int64_t timeout)
224 {
225  int ret;
226  int reuse = 1;
227  if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, sizeof(reuse))) {
228  av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_REUSEADDR) failed\n");
229  }
230  if (srt_bind(fd, addr, addrlen))
231  return libsrt_neterrno(h);
232 
233  if (srt_listen(fd, 1))
234  return libsrt_neterrno(h);
235 
236  ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout, &h->interrupt_callback);
237  if (ret < 0)
238  return ret;
239 
240  ret = srt_accept(fd, NULL, NULL);
241  if (ret < 0)
242  return libsrt_neterrno(h);
243  if (libsrt_socket_nonblock(ret, 1) < 0)
244  av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");
245 
246  return ret;
247 }
248 
249 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)
250 {
251  int ret;
252 
253  if (srt_connect(fd, addr, addrlen) < 0)
254  return libsrt_neterrno(h);
255 
256  ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout, &h->interrupt_callback);
257  if (ret < 0) {
258  if (will_try_next) {
260  "Connection to %s failed (%s), trying next address\n",
261  h->filename, av_err2str(ret));
262  } else {
263  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
264  h->filename, av_err2str(ret));
265  }
266  }
267  return ret;
268 }
269 
270 static int libsrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, const void * optval, int optlen)
271 {
272  if (srt_setsockopt(fd, 0, optname, optval, optlen) < 0) {
273  av_log(h, AV_LOG_ERROR, "failed to set option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
274  return AVERROR(EIO);
275  }
276  return 0;
277 }
278 
279 static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, void * optval, int * optlen)
280 {
281  if (srt_getsockopt(fd, 0, optname, optval, optlen) < 0) {
282  av_log(h, AV_LOG_ERROR, "failed to get option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
283  return AVERROR(EIO);
284  }
285  return 0;
286 }
287 
288 /* - The "POST" options can be altered any time on a connected socket.
289  They MAY have also some meaning when set prior to connecting; such
290  option is SRTO_RCVSYN, which makes connect/accept call asynchronous.
291  Because of that this option is treated special way in this app. */
293 {
294  SRTContext *s = h->priv_data;
295 
296  if ((s->inputbw >= 0 && libsrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) ||
297  (s->oheadbw >= 0 && libsrt_setsockopt(h, fd, SRTO_OHEADBW, "SRTO_OHEADBW", &s->oheadbw, sizeof(s->oheadbw)) < 0)) {
298  return AVERROR(EIO);
299  }
300  return 0;
301 }
302 
303 /* - The "PRE" options must be set prior to connecting and can't be altered
304  on a connected socket, however if set on a listening socket, they are
305  derived by accept-ed socket. */
306 static int libsrt_set_options_pre(URLContext *h, int fd)
307 {
308  SRTContext *s = h->priv_data;
309  int yes = 1;
310  int latency = s->latency / 1000;
311  int rcvlatency = s->rcvlatency / 1000;
312  int peerlatency = s->peerlatency / 1000;
313  int connect_timeout = s->connect_timeout;
314 
315  if ((s->mode == SRT_MODE_RENDEZVOUS && libsrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) ||
316  (s->transtype != SRTT_INVALID && libsrt_setsockopt(h, fd, SRTO_TRANSTYPE, "SRTO_TRANSTYPE", &s->transtype, sizeof(s->transtype)) < 0) ||
317  (s->maxbw >= 0 && libsrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) ||
318  (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
319  (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", s->passphrase, strlen(s->passphrase)) < 0) ||
320 #if SRT_VERSION_VALUE >= 0x010302
321 #if SRT_VERSION_VALUE >= 0x010401
322  (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_ENFORCEDENCRYPTION, "SRTO_ENFORCEDENCRYPTION", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) ||
323 #else
324  /* SRTO_STRICTENC == SRTO_ENFORCEDENCRYPTION (53), but for compatibility, we used SRTO_STRICTENC */
325  (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_STRICTENC, "SRTO_STRICTENC", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) ||
326 #endif
327  (s->kmrefreshrate >= 0 && libsrt_setsockopt(h, fd, SRTO_KMREFRESHRATE, "SRTO_KMREFRESHRATE", &s->kmrefreshrate, sizeof(s->kmrefreshrate)) < 0) ||
328  (s->kmpreannounce >= 0 && libsrt_setsockopt(h, fd, SRTO_KMPREANNOUNCE, "SRTO_KMPREANNOUNCE", &s->kmpreannounce, sizeof(s->kmpreannounce)) < 0) ||
329 #endif
330  (s->mss >= 0 && libsrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MSS", &s->mss, sizeof(s->mss)) < 0) ||
331  (s->ffs >= 0 && libsrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) ||
332  (s->ipttl >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_IPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) ||
333  (s->iptos >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) ||
334  (s->latency >= 0 && libsrt_setsockopt(h, fd, SRTO_LATENCY, "SRTO_LATENCY", &latency, sizeof(latency)) < 0) ||
335  (s->rcvlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_RCVLATENCY, "SRTO_RCVLATENCY", &rcvlatency, sizeof(rcvlatency)) < 0) ||
336  (s->peerlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_PEERLATENCY, "SRTO_PEERLATENCY", &peerlatency, sizeof(peerlatency)) < 0) ||
337  (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKTDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) ||
338  (s->nakreport >= 0 && libsrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) ||
339  (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 ) ||
340  (s->sndbuf >= 0 && libsrt_setsockopt(h, fd, SRTO_SNDBUF, "SRTO_SNDBUF", &s->sndbuf, sizeof(s->sndbuf)) < 0) ||
341  (s->rcvbuf >= 0 && libsrt_setsockopt(h, fd, SRTO_RCVBUF, "SRTO_RCVBUF", &s->rcvbuf, sizeof(s->rcvbuf)) < 0) ||
342  (s->lossmaxttl >= 0 && libsrt_setsockopt(h, fd, SRTO_LOSSMAXTTL, "SRTO_LOSSMAXTTL", &s->lossmaxttl, sizeof(s->lossmaxttl)) < 0) ||
343  (s->minversion >= 0 && libsrt_setsockopt(h, fd, SRTO_MINVERSION, "SRTO_MINVERSION", &s->minversion, sizeof(s->minversion)) < 0) ||
344  (s->streamid && libsrt_setsockopt(h, fd, SRTO_STREAMID, "SRTO_STREAMID", s->streamid, strlen(s->streamid)) < 0) ||
345 #if SRT_VERSION_VALUE >= 0x010401
346  (s->smoother && libsrt_setsockopt(h, fd, SRTO_CONGESTION, "SRTO_CONGESTION", s->smoother, strlen(s->smoother)) < 0) ||
347 #else
348  (s->smoother && libsrt_setsockopt(h, fd, SRTO_SMOOTHER, "SRTO_SMOOTHER", s->smoother, strlen(s->smoother)) < 0) ||
349 #endif
350  (s->messageapi >= 0 && libsrt_setsockopt(h, fd, SRTO_MESSAGEAPI, "SRTO_MESSAGEAPI", &s->messageapi, sizeof(s->messageapi)) < 0) ||
351  (s->payload_size >= 0 && libsrt_setsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &s->payload_size, sizeof(s->payload_size)) < 0) ||
352  ((h->flags & AVIO_FLAG_WRITE) && libsrt_setsockopt(h, fd, SRTO_SENDER, "SRTO_SENDER", &yes, sizeof(yes)) < 0)) {
353  return AVERROR(EIO);
354  }
355 
356  if (s->linger >= 0) {
357  struct linger lin;
358  lin.l_linger = s->linger;
359  lin.l_onoff = lin.l_linger > 0 ? 1 : 0;
360  if (libsrt_setsockopt(h, fd, SRTO_LINGER, "SRTO_LINGER", &lin, sizeof(lin)) < 0)
361  return AVERROR(EIO);
362  }
363  return 0;
364 }
365 
366 
367 static int libsrt_setup(URLContext *h, const char *uri, int flags)
368 {
369  struct addrinfo hints = { 0 }, *ai, *cur_ai;
370  int port, fd;
371  SRTContext *s = h->priv_data;
372  const char *p;
373  char buf[256];
374  int ret;
375  char hostname[1024],proto[1024],path[1024];
376  char portstr[10];
377  int64_t open_timeout = 0;
378  int eid, write_eid;
379 
380  av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
381  &port, path, sizeof(path), uri);
382  if (strcmp(proto, "srt"))
383  return AVERROR(EINVAL);
384  if (port <= 0 || port >= 65536) {
385  av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
386  return AVERROR(EINVAL);
387  }
388  p = strchr(uri, '?');
389  if (p) {
390  if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
391  s->rw_timeout = strtol(buf, NULL, 10);
392  }
393  if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
394  s->listen_timeout = strtol(buf, NULL, 10);
395  }
396  }
397  if (s->rw_timeout >= 0) {
398  open_timeout = h->rw_timeout = s->rw_timeout;
399  }
400  hints.ai_family = AF_UNSPEC;
401  hints.ai_socktype = SOCK_DGRAM;
402  snprintf(portstr, sizeof(portstr), "%d", port);
403  if (s->mode == SRT_MODE_LISTENER)
404  hints.ai_flags |= AI_PASSIVE;
405  ret = getaddrinfo(hostname[0] ? hostname : NULL, portstr, &hints, &ai);
406  if (ret) {
408  "Failed to resolve hostname %s: %s\n",
409  hostname, gai_strerror(ret));
410  return AVERROR(EIO);
411  }
412 
413  cur_ai = ai;
414 
415  restart:
416 
417  fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
418  if (fd < 0) {
419  ret = libsrt_neterrno(h);
420  goto fail;
421  }
422 
423  if ((ret = libsrt_set_options_pre(h, fd)) < 0) {
424  goto fail;
425  }
426 
427  /* Set the socket's send or receive buffer sizes, if specified.
428  If unspecified or setting fails, system default is used. */
429  if (s->recv_buffer_size > 0) {
430  srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size));
431  }
432  if (s->send_buffer_size > 0) {
433  srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size));
434  }
435  if (libsrt_socket_nonblock(fd, 1) < 0)
436  av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");
437 
438  ret = write_eid = libsrt_epoll_create(h, fd, 1);
439  if (ret < 0)
440  goto fail1;
441  if (s->mode == SRT_MODE_LISTENER) {
442  // multi-client
443  ret = libsrt_listen(write_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, s->listen_timeout);
444  srt_epoll_release(write_eid);
445  if (ret < 0)
446  goto fail1;
447  srt_close(fd);
448  fd = ret;
449  } else {
450  if (s->mode == SRT_MODE_RENDEZVOUS) {
451  if (srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) {
452  ret = libsrt_neterrno(h);
453  srt_epoll_release(write_eid);
454  goto fail1;
455  }
456  }
457 
458  ret = libsrt_listen_connect(write_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
459  open_timeout, h, !!cur_ai->ai_next);
460  srt_epoll_release(write_eid);
461  if (ret < 0) {
462  if (ret == AVERROR_EXIT)
463  goto fail1;
464  else
465  goto fail;
466  }
467  }
468  if ((ret = libsrt_set_options_post(h, fd)) < 0) {
469  goto fail;
470  }
471 
472  if (flags & AVIO_FLAG_WRITE) {
473  int packet_size = 0;
474  int optlen = sizeof(packet_size);
475  ret = libsrt_getsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &packet_size, &optlen);
476  if (ret < 0)
477  goto fail1;
478  if (packet_size > 0)
479  h->max_packet_size = packet_size;
480  }
481 
483  if (eid < 0)
484  goto fail1;
485 
486  h->is_streamed = 1;
487  s->fd = fd;
488  s->eid = eid;
489 
490  freeaddrinfo(ai);
491  return 0;
492 
493  fail:
494  if (cur_ai->ai_next) {
495  /* Retry with the next sockaddr */
496  cur_ai = cur_ai->ai_next;
497  if (fd >= 0)
498  srt_close(fd);
499  ret = 0;
500  goto restart;
501  }
502  fail1:
503  if (fd >= 0)
504  srt_close(fd);
505  freeaddrinfo(ai);
506  return ret;
507 }
508 
509 static int libsrt_open(URLContext *h, const char *uri, int flags)
510 {
511  SRTContext *s = h->priv_data;
512  const char * p;
513  char buf[256];
514  int ret = 0;
515 
516  if (srt_startup() < 0) {
517  return AVERROR_UNKNOWN;
518  }
519 
520  /* SRT options (srt/srt.h) */
521  p = strchr(uri, '?');
522  if (p) {
523  if (av_find_info_tag(buf, sizeof(buf), "maxbw", p)) {
524  s->maxbw = strtoll(buf, NULL, 0);
525  }
526  if (av_find_info_tag(buf, sizeof(buf), "pbkeylen", p)) {
527  s->pbkeylen = strtol(buf, NULL, 10);
528  }
529  if (av_find_info_tag(buf, sizeof(buf), "passphrase", p)) {
530  av_freep(&s->passphrase);
531  s->passphrase = av_strndup(buf, strlen(buf));
532  }
533 #if SRT_VERSION_VALUE >= 0x010302
534  if (av_find_info_tag(buf, sizeof(buf), "enforced_encryption", p)) {
535  s->enforced_encryption = strtol(buf, NULL, 10);
536  }
537  if (av_find_info_tag(buf, sizeof(buf), "kmrefreshrate", p)) {
538  s->kmrefreshrate = strtol(buf, NULL, 10);
539  }
540  if (av_find_info_tag(buf, sizeof(buf), "kmpreannounce", p)) {
541  s->kmpreannounce = strtol(buf, NULL, 10);
542  }
543 #endif
544  if (av_find_info_tag(buf, sizeof(buf), "mss", p)) {
545  s->mss = strtol(buf, NULL, 10);
546  }
547  if (av_find_info_tag(buf, sizeof(buf), "ffs", p)) {
548  s->ffs = strtol(buf, NULL, 10);
549  }
550  if (av_find_info_tag(buf, sizeof(buf), "ipttl", p)) {
551  s->ipttl = strtol(buf, NULL, 10);
552  }
553  if (av_find_info_tag(buf, sizeof(buf), "iptos", p)) {
554  s->iptos = strtol(buf, NULL, 10);
555  }
556  if (av_find_info_tag(buf, sizeof(buf), "inputbw", p)) {
557  s->inputbw = strtoll(buf, NULL, 10);
558  }
559  if (av_find_info_tag(buf, sizeof(buf), "oheadbw", p)) {
560  s->oheadbw = strtoll(buf, NULL, 10);
561  }
562  if (av_find_info_tag(buf, sizeof(buf), "latency", p)) {
563  s->latency = strtol(buf, NULL, 10);
564  }
565  if (av_find_info_tag(buf, sizeof(buf), "tsbpddelay", p)) {
566  s->latency = strtol(buf, NULL, 10);
567  }
568  if (av_find_info_tag(buf, sizeof(buf), "rcvlatency", p)) {
569  s->rcvlatency = strtol(buf, NULL, 10);
570  }
571  if (av_find_info_tag(buf, sizeof(buf), "peerlatency", p)) {
572  s->peerlatency = strtol(buf, NULL, 10);
573  }
574  if (av_find_info_tag(buf, sizeof(buf), "tlpktdrop", p)) {
575  s->tlpktdrop = strtol(buf, NULL, 10);
576  }
577  if (av_find_info_tag(buf, sizeof(buf), "nakreport", p)) {
578  s->nakreport = strtol(buf, NULL, 10);
579  }
580  if (av_find_info_tag(buf, sizeof(buf), "connect_timeout", p)) {
581  s->connect_timeout = strtol(buf, NULL, 10);
582  }
583  if (av_find_info_tag(buf, sizeof(buf), "payload_size", p) ||
584  av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
585  s->payload_size = strtol(buf, NULL, 10);
586  }
587  if (av_find_info_tag(buf, sizeof(buf), "mode", p)) {
588  if (!strcmp(buf, "caller")) {
589  s->mode = SRT_MODE_CALLER;
590  } else if (!strcmp(buf, "listener")) {
591  s->mode = SRT_MODE_LISTENER;
592  } else if (!strcmp(buf, "rendezvous")) {
593  s->mode = SRT_MODE_RENDEZVOUS;
594  } else {
595  ret = AVERROR(EINVAL);
596  goto err;
597  }
598  }
599  if (av_find_info_tag(buf, sizeof(buf), "sndbuf", p)) {
600  s->sndbuf = strtol(buf, NULL, 10);
601  }
602  if (av_find_info_tag(buf, sizeof(buf), "rcvbuf", p)) {
603  s->rcvbuf = strtol(buf, NULL, 10);
604  }
605  if (av_find_info_tag(buf, sizeof(buf), "lossmaxttl", p)) {
606  s->lossmaxttl = strtol(buf, NULL, 10);
607  }
608  if (av_find_info_tag(buf, sizeof(buf), "minversion", p)) {
609  s->minversion = strtol(buf, NULL, 0);
610  }
611  if (av_find_info_tag(buf, sizeof(buf), "streamid", p)) {
612  av_freep(&s->streamid);
613  s->streamid = av_strdup(buf);
614  if (!s->streamid) {
615  ret = AVERROR(ENOMEM);
616  goto err;
617  }
618  }
619  if (av_find_info_tag(buf, sizeof(buf), "smoother", p)) {
620  av_freep(&s->smoother);
621  s->smoother = av_strdup(buf);
622  if(!s->smoother) {
623  ret = AVERROR(ENOMEM);
624  goto err;
625  }
626  }
627  if (av_find_info_tag(buf, sizeof(buf), "messageapi", p)) {
628  s->messageapi = strtol(buf, NULL, 10);
629  }
630  if (av_find_info_tag(buf, sizeof(buf), "transtype", p)) {
631  if (!strcmp(buf, "live")) {
632  s->transtype = SRTT_LIVE;
633  } else if (!strcmp(buf, "file")) {
634  s->transtype = SRTT_FILE;
635  } else {
636  ret = AVERROR(EINVAL);
637  goto err;
638  }
639  }
640  if (av_find_info_tag(buf, sizeof(buf), "linger", p)) {
641  s->linger = strtol(buf, NULL, 10);
642  }
643  }
644  ret = libsrt_setup(h, uri, flags);
645  if (ret < 0)
646  goto err;
647  return 0;
648 
649 err:
650  av_freep(&s->smoother);
651  av_freep(&s->streamid);
652  srt_cleanup();
653  return ret;
654 }
655 
656 static int libsrt_read(URLContext *h, uint8_t *buf, int size)
657 {
658  SRTContext *s = h->priv_data;
659  int ret;
660 
661  if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
662  ret = libsrt_network_wait_fd_timeout(h, s->eid, 0, h->rw_timeout, &h->interrupt_callback);
663  if (ret)
664  return ret;
665  }
666 
667  ret = srt_recvmsg(s->fd, buf, size);
668  if (ret < 0) {
669  ret = libsrt_neterrno(h);
670  }
671 
672  return ret;
673 }
674 
675 static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
676 {
677  SRTContext *s = h->priv_data;
678  int ret;
679 
680  if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
681  ret = libsrt_network_wait_fd_timeout(h, s->eid, 1, h->rw_timeout, &h->interrupt_callback);
682  if (ret)
683  return ret;
684  }
685 
686  ret = srt_sendmsg(s->fd, buf, size, -1, 0);
687  if (ret < 0) {
688  ret = libsrt_neterrno(h);
689  }
690 
691  return ret;
692 }
693 
695 {
696  SRTContext *s = h->priv_data;
697 
698  srt_epoll_release(s->eid);
699  srt_close(s->fd);
700 
701  srt_cleanup();
702 
703  return 0;
704 }
705 
707 {
708  SRTContext *s = h->priv_data;
709  return s->fd;
710 }
711 
712 static const AVClass libsrt_class = {
713  .class_name = "libsrt",
714  .item_name = av_default_item_name,
715  .option = libsrt_options,
716  .version = LIBAVUTIL_VERSION_INT,
717 };
718 
720  .name = "srt",
721  .url_open = libsrt_open,
722  .url_read = libsrt_read,
723  .url_write = libsrt_write,
724  .url_close = libsrt_close,
725  .url_get_file_handle = libsrt_get_file_handle,
726  .priv_data_size = sizeof(SRTContext),
728  .priv_data_class = &libsrt_class,
729 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:30
av_gettime_relative
int64_t av_gettime_relative(void)
Get the current time in microseconds since some unspecified starting point.
Definition: time.c:56
AV_LOG_WARNING
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:200
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later. That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another. Frame references ownership and permissions
opt.h
av_find_info_tag
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.
Definition: parseutils.c:751
SRTContext::ffs
int ffs
Definition: libsrt.c:71
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:34
SRTContext::mode
enum SRTMode mode
Definition: libsrt.c:83
SRT_LIVE_DEFAULT_PAYLOAD_SIZE
#define SRT_LIVE_DEFAULT_PAYLOAD_SIZE
Definition: libsrt.c:39
libsrt_network_wait_fd_timeout
static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int write, int64_t timeout, AVIOInterruptCB *int_cb)
Definition: libsrt.c:203
SRTContext::sndbuf
int sndbuf
Definition: libsrt.c:84
SRTContext
Definition: srtenc.c:32
AVOption
AVOption.
Definition: opt.h:248
SRTContext::pbkeylen
int pbkeylen
Definition: libsrt.c:63
libsrt_getsockopt
static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char *optnamestr, void *optval, int *optlen)
Definition: libsrt.c:279
SRT_MODE_CALLER
@ SRT_MODE_CALLER
Definition: libsrt.c:48
AVERROR_UNKNOWN
#define AVERROR_UNKNOWN
Unknown error, typically from an external library.
Definition: error.h:71
SRTContext::fd
int fd
Definition: libsrt.c:55
URLProtocol
Definition: url.h:54
D
#define D
Definition: libsrt.c:95
os_support.h
OFFSET
#define OFFSET(x)
Definition: libsrt.c:97
AVIOInterruptCB
Callback for checking whether to abort blocking functions.
Definition: avio.h:58
SRTContext::smoother
char * smoother
Definition: libsrt.c:89
SRT_MODE_LISTENER
@ SRT_MODE_LISTENER
Definition: libsrt.c:49
SRTContext::streamid
char * streamid
Definition: libsrt.c:88
freeaddrinfo
#define freeaddrinfo
Definition: network.h:218
SRTContext::listen_timeout
int64_t listen_timeout
Definition: libsrt.c:58
SRTContext::eid
int eid
Definition: libsrt.c:56
fail
#define fail()
Definition: checkasm.h:133
SRTContext::ipttl
int ipttl
Definition: libsrt.c:72
SRTContext::recv_buffer_size
int recv_buffer_size
Definition: libsrt.c:59
libsrt_network_wait_fd
static int libsrt_network_wait_fd(URLContext *h, int eid, int write)
Definition: libsrt.c:179
ff_check_interrupt
int ff_check_interrupt(AVIOInterruptCB *cb)
Check if the user has requested to interrupt a blocking function associated with cb.
Definition: avio.c:658
SRTContext::oheadbw
int oheadbw
Definition: libsrt.c:75
libsrt_open
static int libsrt_open(URLContext *h, const char *uri, int flags)
Definition: libsrt.c:509
SRTContext::minversion
int minversion
Definition: libsrt.c:87
avassert.h
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
ff_libsrt_protocol
const URLProtocol ff_libsrt_protocol
Definition: libsrt.c:719
s
#define s(width, name)
Definition: cbs_vp9.c:257
libsrt_epoll_create
static int libsrt_epoll_create(URLContext *h, int fd, int write)
Definition: libsrt.c:166
libsrt_setsockopt
static int libsrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char *optnamestr, const void *optval, int optlen)
Definition: libsrt.c:270
libsrt_get_file_handle
static int libsrt_get_file_handle(URLContext *h)
Definition: libsrt.c:706
SRTContext::maxbw
int64_t maxbw
Definition: libsrt.c:62
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:226
SRTContext::rcvlatency
int64_t rcvlatency
Definition: libsrt.c:81
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:675
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
libsrt_options
static const AVOption libsrt_options[]
Definition: libsrt.c:98
libsrt_listen
static int libsrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int64_t timeout)
Definition: libsrt.c:223
libsrt_set_options_pre
static int libsrt_set_options_pre(URLContext *h, int fd)
Definition: libsrt.c:306
internal.h
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
libsrt_socket_nonblock
static int libsrt_socket_nonblock(int socket, int enable)
Definition: libsrt.c:156
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
SRTContext::lossmaxttl
int lossmaxttl
Definition: libsrt.c:86
SRTContext::transtype
SRT_TRANSTYPE transtype
Definition: libsrt.c:91
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:235
parseutils.h
libsrt_set_options_post
static int libsrt_set_options_post(URLContext *h, int fd)
Definition: libsrt.c:292
time.h
addrinfo::ai_family
int ai_family
Definition: network.h:139
SRTContext::payload_size
int payload_size
Definition: libsrt.c:80
SRTContext::inputbw
int64_t inputbw
Definition: libsrt.c:74
av_err2str
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition: error.h:119
size
int size
Definition: twinvq_data.h:10344
SRTContext::linger
int linger
Definition: libsrt.c:92
E
#define E
Definition: libsrt.c:96
URLProtocol::name
const char * name
Definition: url.h:55
libsrt_write
static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
Definition: libsrt.c:675
SRT_LIVE_MAX_PAYLOAD_SIZE
#define SRT_LIVE_MAX_PAYLOAD_SIZE
Definition: libsrt.c:44
gai_strerror
#define gai_strerror
Definition: network.h:225
getaddrinfo
#define getaddrinfo
Definition: network.h:217
SRT_MODE_RENDEZVOUS
@ SRT_MODE_RENDEZVOUS
Definition: libsrt.c:50
SRTContext::rw_timeout
int64_t rw_timeout
Definition: libsrt.c:57
URLContext
Definition: url.h:38
modes
static const SiprModeParam modes[MODE_COUNT]
Definition: sipr.c:69
else
else
Definition: snow.txt:125
av_url_split
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.
Definition: utils.c:4847
url.h
uint8_t
uint8_t
Definition: audio_convert.c:194
SRTContext::send_buffer_size
int send_buffer_size
Definition: libsrt.c:60
len
int len
Definition: vorbis_enc_data.h:452
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:513
ret
ret
Definition: filter_design.txt:187
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
addrinfo::ai_socktype
int ai_socktype
Definition: network.h:140
SRTContext::peerlatency
int64_t peerlatency
Definition: libsrt.c:82
SRTContext::passphrase
char * passphrase
Definition: libsrt.c:64
avformat.h
network.h
SRTContext::messageapi
int messageapi
Definition: libsrt.c:90
addrinfo::ai_flags
int ai_flags
Definition: network.h:138
mode
mode
Definition: ebur128.h:83
AV_OPT_TYPE_INT
@ AV_OPT_TYPE_INT
Definition: opt.h:225
libsrt_class
static const AVClass libsrt_class
Definition: libsrt.c:712
SRTContext::connect_timeout
int64_t connect_timeout
Definition: libsrt.c:79
libsrt_read
static int libsrt_read(URLContext *h, uint8_t *buf, int size)
Definition: libsrt.c:656
libsrt_setup
static int libsrt_setup(URLContext *h, const char *uri, int flags)
Definition: libsrt.c:367
libsrt_listen_connect
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)
Definition: libsrt.c:249
libsrt_close
static int libsrt_close(URLContext *h)
Definition: libsrt.c:694
av_strdup
char * av_strdup(const char *s)
Duplicate a string.
Definition: mem.c:253
SRTContext::iptos
int iptos
Definition: libsrt.c:73
SRTContext::rcvbuf
int rcvbuf
Definition: libsrt.c:85
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:242
SRTContext::latency
int64_t latency
Definition: libsrt.c:76
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:693
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
ready
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already ready
Definition: filter_design.txt:258
POLLING_TIME
#define POLLING_TIME
Definition: network.h:249
SRTContext::nakreport
int nakreport
Definition: libsrt.c:78
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
h
h
Definition: vp9dsp_template.c:2038
AVERROR_EXIT
#define AVERROR_EXIT
Immediate exit was requested; the called function should not be restarted.
Definition: error.h:56
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:229
addrinfo
Definition: network.h:137
av_strndup
char * av_strndup(const char *s, size_t len)
Duplicate a substring of a string.
Definition: mem.c:265
libsrt_neterrno
static int libsrt_neterrno(URLContext *h)
Definition: libsrt.c:146
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:234
snprintf
#define snprintf
Definition: snprintf.h:34
SRTMode
SRTMode
Definition: libsrt.c:47
SRTContext::mss
int mss
Definition: libsrt.c:70
AI_PASSIVE
#define AI_PASSIVE
Definition: network.h:179
SRTContext::tlpktdrop
int tlpktdrop
Definition: libsrt.c:77