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/opt.h"
27 #include "libavutil/parseutils.h"
28 #include "libavutil/time.h"
29 
30 #include "avformat.h"
31 #include "internal.h"
32 #include "network.h"
33 #include "os_support.h"
34 #include "url.h"
35 #include "urldecode.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;
61 
63  int pbkeylen;
64  char *passphrase;
65 #if SRT_VERSION_VALUE >= 0x010302
66  int enforced_encryption;
67  int kmrefreshrate;
68  int kmpreannounce;
69  int64_t snddropdelay;
70 #endif
71  int mss;
72  int ffs;
73  int ipttl;
74  int iptos;
76  int oheadbw;
78  int tlpktdrop;
79  int nakreport;
84  enum SRTMode mode;
85  int sndbuf;
86  int rcvbuf;
89  char *streamid;
90  char *smoother;
92  SRT_TRANSTYPE transtype;
93  int linger;
94  int tsbpd;
95 } SRTContext;
96 
97 #define D AV_OPT_FLAG_DECODING_PARAM
98 #define E AV_OPT_FLAG_ENCODING_PARAM
99 #define OFFSET(x) offsetof(SRTContext, x)
100 static const AVOption libsrt_options[] = {
101  { "timeout", "Timeout of socket I/O operations (in microseconds)", OFFSET(rw_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
102  { "listen_timeout", "Connection awaiting timeout (in microseconds)" , OFFSET(listen_timeout), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
103  { "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 },
104  { "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 },
105  { "pkt_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, .unit = "payload_size" },
106  { "payload_size", "Maximum SRT packet size", OFFSET(payload_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, SRT_LIVE_MAX_PAYLOAD_SIZE, .flags = D|E, .unit = "payload_size" },
107  { "ts_size", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_LIVE_DEFAULT_PAYLOAD_SIZE }, INT_MIN, INT_MAX, .flags = D|E, .unit = "payload_size" },
108  { "max_size", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_LIVE_MAX_PAYLOAD_SIZE }, INT_MIN, INT_MAX, .flags = D|E, .unit = "payload_size" },
109  { "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 },
110  { "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 },
111  { "passphrase", "Crypto PBKDF2 Passphrase size[0,10..64] 0:disable crypto", OFFSET(passphrase), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
112 #if SRT_VERSION_VALUE >= 0x010302
113  { "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 },
114  { "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 },
115  { "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  { "snddropdelay", "The sender's extra delay(in microseconds) before dropping packets", OFFSET(snddropdelay), AV_OPT_TYPE_INT64, { .i64 = -2 }, -2, INT64_MAX, .flags = D|E },
117 #endif
118  { "mss", "The Maximum Segment Size", OFFSET(mss), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 1500, .flags = D|E },
119  { "ffs", "Flight flag size (window size) (in bytes)", OFFSET(ffs), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
120  { "ipttl", "IP Time To Live", OFFSET(ipttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
121  { "iptos", "IP Type of Service", OFFSET(iptos), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 255, .flags = D|E },
122  { "inputbw", "Estimated input stream rate", OFFSET(inputbw), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
123  { "oheadbw", "MaxBW ceiling based on % over input stream rate", OFFSET(oheadbw), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, 100, .flags = D|E },
124  { "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 },
125  { "tsbpddelay", "deprecated, same effect as latency option", OFFSET(latency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
126  { "rcvlatency", "receive latency (in microseconds)", OFFSET(rcvlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
127  { "peerlatency", "peer latency (in microseconds)", OFFSET(peerlatency), AV_OPT_TYPE_INT64, { .i64 = -1 }, -1, INT64_MAX, .flags = D|E },
128  { "tlpktdrop", "Enable too-late pkt drop", OFFSET(tlpktdrop), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
129  { "nakreport", "Enable receiver to send periodic NAK reports", OFFSET(nakreport), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
130  { "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 },
131  { "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, .unit = "mode" },
132  { "caller", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_CALLER }, INT_MIN, INT_MAX, .flags = D|E, .unit = "mode" },
133  { "listener", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_LISTENER }, INT_MIN, INT_MAX, .flags = D|E, .unit = "mode" },
134  { "rendezvous", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRT_MODE_RENDEZVOUS }, INT_MIN, INT_MAX, .flags = D|E, .unit = "mode" },
135  { "sndbuf", "Send buffer size (in bytes)", OFFSET(sndbuf), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
136  { "rcvbuf", "Receive buffer size (in bytes)", OFFSET(rcvbuf), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
137  { "lossmaxttl", "Maximum possible packet reorder tolerance", OFFSET(lossmaxttl), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, .flags = D|E },
138  { "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 },
139  { "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 },
140  { "srt_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 },
141  { "smoother", "The type of Smoother used for the transmission for that socket", OFFSET(smoother), AV_OPT_TYPE_STRING, { .str = NULL }, .flags = D|E },
142  { "messageapi", "Enable message API", OFFSET(messageapi), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
143  { "transtype", "The transmission type for the socket", OFFSET(transtype), AV_OPT_TYPE_INT, { .i64 = SRTT_INVALID }, SRTT_LIVE, SRTT_INVALID, .flags = D|E, .unit = "transtype" },
144  { "live", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRTT_LIVE }, INT_MIN, INT_MAX, .flags = D|E, .unit = "transtype" },
145  { "file", NULL, 0, AV_OPT_TYPE_CONST, { .i64 = SRTT_FILE }, INT_MIN, INT_MAX, .flags = D|E, .unit = "transtype" },
146  { "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 },
147  { "tsbpd", "Timestamp-based packet delivery", OFFSET(tsbpd), AV_OPT_TYPE_BOOL, { .i64 = -1 }, -1, 1, .flags = D|E },
148  { NULL }
149 };
150 
152 {
153  int os_errno;
154  int err = srt_getlasterror(&os_errno);
155  if (err == SRT_EASYNCRCV || err == SRT_EASYNCSND)
156  return AVERROR(EAGAIN);
157  av_log(h, AV_LOG_ERROR, "%s\n", srt_getlasterror_str());
158  return os_errno ? AVERROR(os_errno) : AVERROR_UNKNOWN;
159 }
160 
161 static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, void * optval, int * optlen)
162 {
163  if (srt_getsockopt(fd, 0, optname, optval, optlen) < 0) {
164  av_log(h, AV_LOG_ERROR, "failed to get option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
165  return AVERROR(EIO);
166  }
167  return 0;
168 }
169 
170 static int libsrt_socket_nonblock(int socket, int enable)
171 {
172  int ret, blocking = enable ? 0 : 1;
173  /* Setting SRTO_{SND,RCV}SYN options to 1 enable blocking mode, setting them to 0 enable non-blocking mode. */
174  ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &blocking, sizeof(blocking));
175  if (ret < 0)
176  return ret;
177  return srt_setsockopt(socket, 0, SRTO_RCVSYN, &blocking, sizeof(blocking));
178 }
179 
180 static int libsrt_epoll_create(URLContext *h, int fd, int write)
181 {
182  int modes = SRT_EPOLL_ERR | (write ? SRT_EPOLL_OUT : SRT_EPOLL_IN);
183  int eid = srt_epoll_create();
184  if (eid < 0)
185  return libsrt_neterrno(h);
186  if (srt_epoll_add_usock(eid, fd, &modes) < 0) {
187  srt_epoll_release(eid);
188  return libsrt_neterrno(h);
189  }
190  return eid;
191 }
192 
193 static int libsrt_network_wait_fd(URLContext *h, int eid, int write)
194 {
195  int ret, len = 1, errlen = 1;
196  SRTSOCKET ready[1];
197  SRTSOCKET error[1];
198 
199  if (write) {
200  ret = srt_epoll_wait(eid, error, &errlen, ready, &len, POLLING_TIME, 0, 0, 0, 0);
201  } else {
202  ret = srt_epoll_wait(eid, ready, &len, error, &errlen, POLLING_TIME, 0, 0, 0, 0);
203  }
204  if (ret < 0) {
205  if (srt_getlasterror(NULL) == SRT_ETIMEOUT)
206  ret = AVERROR(EAGAIN);
207  else
208  ret = libsrt_neterrno(h);
209  } else {
210  ret = errlen ? AVERROR(EIO) : 0;
211  }
212  return ret;
213 }
214 
215 /* TODO de-duplicate code from ff_network_wait_fd_timeout() */
216 
217 static int libsrt_network_wait_fd_timeout(URLContext *h, int eid, int write, int64_t timeout, AVIOInterruptCB *int_cb)
218 {
219  int ret;
220  int64_t wait_start = 0;
221 
222  while (1) {
224  return AVERROR_EXIT;
225  ret = libsrt_network_wait_fd(h, eid, write);
226  if (ret != AVERROR(EAGAIN))
227  return ret;
228  if (timeout > 0) {
229  if (!wait_start)
230  wait_start = av_gettime_relative();
231  else if (av_gettime_relative() - wait_start > timeout)
232  return AVERROR(ETIMEDOUT);
233  }
234  }
235 }
236 
237 static int libsrt_listen(int eid, int fd, const struct sockaddr *addr, socklen_t addrlen, URLContext *h, int64_t timeout)
238 {
239  int ret;
240  int reuse = 1;
241  /* Max streamid length plus an extra space for the terminating null character */
242  char streamid[513];
243  int streamid_len = sizeof(streamid);
244  if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, sizeof(reuse))) {
245  av_log(h, AV_LOG_WARNING, "setsockopt(SRTO_REUSEADDR) failed\n");
246  }
247  if (srt_bind(fd, addr, addrlen))
248  return libsrt_neterrno(h);
249 
250  if (srt_listen(fd, 1))
251  return libsrt_neterrno(h);
252 
253  ret = libsrt_network_wait_fd_timeout(h, eid, 0, timeout, &h->interrupt_callback);
254  if (ret < 0)
255  return ret;
256 
257  ret = srt_accept(fd, NULL, NULL);
258  if (ret < 0)
259  return libsrt_neterrno(h);
260  if (libsrt_socket_nonblock(ret, 1) < 0)
261  av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");
262  if (!libsrt_getsockopt(h, ret, SRTO_STREAMID, "SRTO_STREAMID", streamid, &streamid_len))
263  /* Note: returned streamid_len doesn't count the terminating null character */
264  av_log(h, AV_LOG_VERBOSE, "accept streamid [%s], length %d\n", streamid, streamid_len);
265 
266  return ret;
267 }
268 
269 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)
270 {
271  int ret;
272 
273  if (srt_connect(fd, addr, addrlen) < 0)
274  return libsrt_neterrno(h);
275 
276  ret = libsrt_network_wait_fd_timeout(h, eid, 1, timeout, &h->interrupt_callback);
277  if (ret < 0) {
278  if (will_try_next) {
280  "Connection to %s failed (%s), trying next address\n",
281  h->filename, av_err2str(ret));
282  } else {
283  av_log(h, AV_LOG_ERROR, "Connection to %s failed: %s\n",
284  h->filename, av_err2str(ret));
285  }
286  }
287  return ret;
288 }
289 
290 static int libsrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char * optnamestr, const void * optval, int optlen)
291 {
292  if (srt_setsockopt(fd, 0, optname, optval, optlen) < 0) {
293  av_log(h, AV_LOG_ERROR, "failed to set option %s on socket: %s\n", optnamestr, srt_getlasterror_str());
294  return AVERROR(EIO);
295  }
296  return 0;
297 }
298 
299 /* - The "POST" options can be altered any time on a connected socket.
300  They MAY have also some meaning when set prior to connecting; such
301  option is SRTO_RCVSYN, which makes connect/accept call asynchronous.
302  Because of that this option is treated special way in this app. */
304 {
305  SRTContext *s = h->priv_data;
306 
307  if ((s->inputbw >= 0 && libsrt_setsockopt(h, fd, SRTO_INPUTBW, "SRTO_INPUTBW", &s->inputbw, sizeof(s->inputbw)) < 0) ||
308  (s->oheadbw >= 0 && libsrt_setsockopt(h, fd, SRTO_OHEADBW, "SRTO_OHEADBW", &s->oheadbw, sizeof(s->oheadbw)) < 0)) {
309  return AVERROR(EIO);
310  }
311  return 0;
312 }
313 
314 /* - The "PRE" options must be set prior to connecting and can't be altered
315  on a connected socket, however if set on a listening socket, they are
316  derived by accept-ed socket. */
317 static int libsrt_set_options_pre(URLContext *h, int fd)
318 {
319  SRTContext *s = h->priv_data;
320  int yes = 1;
321  int latency = s->latency / 1000;
322  int rcvlatency = s->rcvlatency / 1000;
323  int peerlatency = s->peerlatency / 1000;
324 #if SRT_VERSION_VALUE >= 0x010302
325  int snddropdelay = s->snddropdelay > 0 ? s->snddropdelay / 1000 : s->snddropdelay;
326 #endif
327  int connect_timeout = s->connect_timeout;
328 
329  if ((s->mode == SRT_MODE_RENDEZVOUS && libsrt_setsockopt(h, fd, SRTO_RENDEZVOUS, "SRTO_RENDEZVOUS", &yes, sizeof(yes)) < 0) ||
330  (s->transtype != SRTT_INVALID && libsrt_setsockopt(h, fd, SRTO_TRANSTYPE, "SRTO_TRANSTYPE", &s->transtype, sizeof(s->transtype)) < 0) ||
331  (s->maxbw >= 0 && libsrt_setsockopt(h, fd, SRTO_MAXBW, "SRTO_MAXBW", &s->maxbw, sizeof(s->maxbw)) < 0) ||
332  (s->pbkeylen >= 0 && libsrt_setsockopt(h, fd, SRTO_PBKEYLEN, "SRTO_PBKEYLEN", &s->pbkeylen, sizeof(s->pbkeylen)) < 0) ||
333  (s->passphrase && libsrt_setsockopt(h, fd, SRTO_PASSPHRASE, "SRTO_PASSPHRASE", s->passphrase, strlen(s->passphrase)) < 0) ||
334 #if SRT_VERSION_VALUE >= 0x010302
335 #if SRT_VERSION_VALUE >= 0x010401
336  (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_ENFORCEDENCRYPTION, "SRTO_ENFORCEDENCRYPTION", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) ||
337 #else
338  /* SRTO_STRICTENC == SRTO_ENFORCEDENCRYPTION (53), but for compatibility, we used SRTO_STRICTENC */
339  (s->enforced_encryption >= 0 && libsrt_setsockopt(h, fd, SRTO_STRICTENC, "SRTO_STRICTENC", &s->enforced_encryption, sizeof(s->enforced_encryption)) < 0) ||
340 #endif
341  (s->kmrefreshrate >= 0 && libsrt_setsockopt(h, fd, SRTO_KMREFRESHRATE, "SRTO_KMREFRESHRATE", &s->kmrefreshrate, sizeof(s->kmrefreshrate)) < 0) ||
342  (s->kmpreannounce >= 0 && libsrt_setsockopt(h, fd, SRTO_KMPREANNOUNCE, "SRTO_KMPREANNOUNCE", &s->kmpreannounce, sizeof(s->kmpreannounce)) < 0) ||
343  (s->snddropdelay >=-1 && libsrt_setsockopt(h, fd, SRTO_SNDDROPDELAY, "SRTO_SNDDROPDELAY", &snddropdelay, sizeof(snddropdelay)) < 0) ||
344 #endif
345  (s->mss >= 0 && libsrt_setsockopt(h, fd, SRTO_MSS, "SRTO_MSS", &s->mss, sizeof(s->mss)) < 0) ||
346  (s->ffs >= 0 && libsrt_setsockopt(h, fd, SRTO_FC, "SRTO_FC", &s->ffs, sizeof(s->ffs)) < 0) ||
347  (s->ipttl >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTTL, "SRTO_IPTTL", &s->ipttl, sizeof(s->ipttl)) < 0) ||
348  (s->iptos >= 0 && libsrt_setsockopt(h, fd, SRTO_IPTOS, "SRTO_IPTOS", &s->iptos, sizeof(s->iptos)) < 0) ||
349  (s->latency >= 0 && libsrt_setsockopt(h, fd, SRTO_LATENCY, "SRTO_LATENCY", &latency, sizeof(latency)) < 0) ||
350  (s->rcvlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_RCVLATENCY, "SRTO_RCVLATENCY", &rcvlatency, sizeof(rcvlatency)) < 0) ||
351  (s->peerlatency >= 0 && libsrt_setsockopt(h, fd, SRTO_PEERLATENCY, "SRTO_PEERLATENCY", &peerlatency, sizeof(peerlatency)) < 0) ||
352  (s->tlpktdrop >= 0 && libsrt_setsockopt(h, fd, SRTO_TLPKTDROP, "SRTO_TLPKTDROP", &s->tlpktdrop, sizeof(s->tlpktdrop)) < 0) ||
353  (s->nakreport >= 0 && libsrt_setsockopt(h, fd, SRTO_NAKREPORT, "SRTO_NAKREPORT", &s->nakreport, sizeof(s->nakreport)) < 0) ||
354  (connect_timeout >= 0 && libsrt_setsockopt(h, fd, SRTO_CONNTIMEO, "SRTO_CONNTIMEO", &connect_timeout, sizeof(connect_timeout)) <0 ) ||
355  (s->sndbuf >= 0 && libsrt_setsockopt(h, fd, SRTO_SNDBUF, "SRTO_SNDBUF", &s->sndbuf, sizeof(s->sndbuf)) < 0) ||
356  (s->rcvbuf >= 0 && libsrt_setsockopt(h, fd, SRTO_RCVBUF, "SRTO_RCVBUF", &s->rcvbuf, sizeof(s->rcvbuf)) < 0) ||
357  (s->lossmaxttl >= 0 && libsrt_setsockopt(h, fd, SRTO_LOSSMAXTTL, "SRTO_LOSSMAXTTL", &s->lossmaxttl, sizeof(s->lossmaxttl)) < 0) ||
358  (s->minversion >= 0 && libsrt_setsockopt(h, fd, SRTO_MINVERSION, "SRTO_MINVERSION", &s->minversion, sizeof(s->minversion)) < 0) ||
359  (s->streamid && libsrt_setsockopt(h, fd, SRTO_STREAMID, "SRTO_STREAMID", s->streamid, strlen(s->streamid)) < 0) ||
360 #if SRT_VERSION_VALUE >= 0x010401
361  (s->smoother && libsrt_setsockopt(h, fd, SRTO_CONGESTION, "SRTO_CONGESTION", s->smoother, strlen(s->smoother)) < 0) ||
362 #else
363  (s->smoother && libsrt_setsockopt(h, fd, SRTO_SMOOTHER, "SRTO_SMOOTHER", s->smoother, strlen(s->smoother)) < 0) ||
364 #endif
365  (s->messageapi >= 0 && libsrt_setsockopt(h, fd, SRTO_MESSAGEAPI, "SRTO_MESSAGEAPI", &s->messageapi, sizeof(s->messageapi)) < 0) ||
366  (s->payload_size >= 0 && libsrt_setsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &s->payload_size, sizeof(s->payload_size)) < 0) ||
367  ((h->flags & AVIO_FLAG_WRITE) && libsrt_setsockopt(h, fd, SRTO_SENDER, "SRTO_SENDER", &yes, sizeof(yes)) < 0) ||
368  (s->tsbpd >= 0 && libsrt_setsockopt(h, fd, SRTO_TSBPDMODE, "SRTO_TSBPDMODE", &s->tsbpd, sizeof(s->tsbpd)) < 0)) {
369  return AVERROR(EIO);
370  }
371 
372  if (s->linger >= 0) {
373  struct linger lin;
374  lin.l_linger = s->linger;
375  lin.l_onoff = lin.l_linger > 0 ? 1 : 0;
376  if (libsrt_setsockopt(h, fd, SRTO_LINGER, "SRTO_LINGER", &lin, sizeof(lin)) < 0)
377  return AVERROR(EIO);
378  }
379  return 0;
380 }
381 
382 
383 static int libsrt_setup(URLContext *h, const char *uri, int flags)
384 {
385  struct addrinfo hints = { 0 }, *ai, *cur_ai;
386  int port, fd;
387  SRTContext *s = h->priv_data;
388  const char *p;
389  char buf[256];
390  int ret;
391  char hostname[1024],proto[1024],path[1024];
392  char portstr[10];
393  int64_t open_timeout = 0;
394  int eid;
395 
396  av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
397  &port, path, sizeof(path), uri);
398  if (strcmp(proto, "srt"))
399  return AVERROR(EINVAL);
400  if (port <= 0 || port >= 65536) {
401  av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
402  return AVERROR(EINVAL);
403  }
404  p = strchr(uri, '?');
405  if (p) {
406  if (av_find_info_tag(buf, sizeof(buf), "timeout", p)) {
407  s->rw_timeout = strtoll(buf, NULL, 10);
408  }
409  if (av_find_info_tag(buf, sizeof(buf), "listen_timeout", p)) {
410  s->listen_timeout = strtoll(buf, NULL, 10);
411  }
412  }
413  if (s->rw_timeout >= 0) {
414  open_timeout = h->rw_timeout = s->rw_timeout;
415  }
416  hints.ai_family = AF_UNSPEC;
417  hints.ai_socktype = SOCK_DGRAM;
418  snprintf(portstr, sizeof(portstr), "%d", port);
419  if (s->mode == SRT_MODE_LISTENER)
420  hints.ai_flags |= AI_PASSIVE;
421  ret = getaddrinfo(hostname[0] ? hostname : NULL, portstr, &hints, &ai);
422  if (ret) {
424  "Failed to resolve hostname %s: %s\n",
425  hostname, gai_strerror(ret));
426  return AVERROR(EIO);
427  }
428 
429  cur_ai = ai;
430 
431  restart:
432 
433 #if SRT_VERSION_VALUE >= 0x010401
434  fd = srt_create_socket();
435 #else
436  fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
437 #endif
438  if (fd < 0) {
439  ret = libsrt_neterrno(h);
440  goto fail;
441  }
442 
443  if ((ret = libsrt_set_options_pre(h, fd)) < 0) {
444  goto fail;
445  }
446 
447  /* Set the socket's send or receive buffer sizes, if specified.
448  If unspecified or setting fails, system default is used. */
449  if (s->recv_buffer_size > 0) {
450  srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_RCVBUF, &s->recv_buffer_size, sizeof (s->recv_buffer_size));
451  }
452  if (s->send_buffer_size > 0) {
453  srt_setsockopt(fd, SOL_SOCKET, SRTO_UDP_SNDBUF, &s->send_buffer_size, sizeof (s->send_buffer_size));
454  }
455  if (libsrt_socket_nonblock(fd, 1) < 0)
456  av_log(h, AV_LOG_DEBUG, "libsrt_socket_nonblock failed\n");
457 
458  if (s->mode == SRT_MODE_LISTENER) {
459  int read_eid = ret = libsrt_epoll_create(h, fd, 0);
460  if (ret < 0)
461  goto fail1;
462  // multi-client
463  ret = libsrt_listen(read_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen, h, s->listen_timeout);
464  srt_epoll_release(read_eid);
465  if (ret < 0)
466  goto fail1;
467  srt_close(fd);
468  fd = ret;
469  } else {
470  int write_eid = ret = libsrt_epoll_create(h, fd, 1);
471  if (ret < 0)
472  goto fail1;
473  if (s->mode == SRT_MODE_RENDEZVOUS) {
474  if (srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) {
475  ret = libsrt_neterrno(h);
476  srt_epoll_release(write_eid);
477  goto fail1;
478  }
479  }
480 
481  ret = libsrt_listen_connect(write_eid, fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
482  open_timeout, h, !!cur_ai->ai_next);
483  srt_epoll_release(write_eid);
484  if (ret < 0) {
485  if (ret == AVERROR_EXIT)
486  goto fail1;
487  else
488  goto fail;
489  }
490  }
491  if ((ret = libsrt_set_options_post(h, fd)) < 0) {
492  goto fail;
493  }
494 
495  if (flags & AVIO_FLAG_WRITE) {
496  int packet_size = 0;
497  int optlen = sizeof(packet_size);
498  ret = libsrt_getsockopt(h, fd, SRTO_PAYLOADSIZE, "SRTO_PAYLOADSIZE", &packet_size, &optlen);
499  if (ret < 0)
500  goto fail1;
501  if (packet_size > 0)
502  h->max_packet_size = packet_size;
503  }
504 
506  if (eid < 0)
507  goto fail1;
508 
509  h->is_streamed = 1;
510  s->fd = fd;
511  s->eid = eid;
512 
513  freeaddrinfo(ai);
514  return 0;
515 
516  fail:
517  if (cur_ai->ai_next) {
518  /* Retry with the next sockaddr */
519  cur_ai = cur_ai->ai_next;
520  if (fd >= 0)
521  srt_close(fd);
522  ret = 0;
523  goto restart;
524  }
525  fail1:
526  if (fd >= 0)
527  srt_close(fd);
528  freeaddrinfo(ai);
529  return ret;
530 }
531 
532 static int libsrt_open(URLContext *h, const char *uri, int flags)
533 {
534  SRTContext *s = h->priv_data;
535  const char * p;
536  char buf[1024];
537  int ret = 0;
538 
539  if (srt_startup() < 0) {
540  return AVERROR_UNKNOWN;
541  }
542 
543  /* SRT options (srt/srt.h) */
544  p = strchr(uri, '?');
545  if (p) {
546  if (av_find_info_tag(buf, sizeof(buf), "maxbw", p)) {
547  s->maxbw = strtoll(buf, NULL, 10);
548  }
549  if (av_find_info_tag(buf, sizeof(buf), "pbkeylen", p)) {
550  s->pbkeylen = strtol(buf, NULL, 10);
551  }
552  if (av_find_info_tag(buf, sizeof(buf), "passphrase", p)) {
553  av_freep(&s->passphrase);
554  s->passphrase = ff_urldecode(buf, 1);
555  if (!s->passphrase) {
556  ret = AVERROR(ENOMEM);
557  goto err;
558  }
559  }
560 #if SRT_VERSION_VALUE >= 0x010302
561  if (av_find_info_tag(buf, sizeof(buf), "enforced_encryption", p)) {
562  s->enforced_encryption = strtol(buf, NULL, 10);
563  }
564  if (av_find_info_tag(buf, sizeof(buf), "kmrefreshrate", p)) {
565  s->kmrefreshrate = strtol(buf, NULL, 10);
566  }
567  if (av_find_info_tag(buf, sizeof(buf), "kmpreannounce", p)) {
568  s->kmpreannounce = strtol(buf, NULL, 10);
569  }
570  if (av_find_info_tag(buf, sizeof(buf), "snddropdelay", p)) {
571  s->snddropdelay = strtoll(buf, NULL, 10);
572  }
573 #endif
574  if (av_find_info_tag(buf, sizeof(buf), "mss", p)) {
575  s->mss = strtol(buf, NULL, 10);
576  }
577  if (av_find_info_tag(buf, sizeof(buf), "ffs", p)) {
578  s->ffs = strtol(buf, NULL, 10);
579  }
580  if (av_find_info_tag(buf, sizeof(buf), "ipttl", p)) {
581  s->ipttl = strtol(buf, NULL, 10);
582  }
583  if (av_find_info_tag(buf, sizeof(buf), "iptos", p)) {
584  s->iptos = strtol(buf, NULL, 10);
585  }
586  if (av_find_info_tag(buf, sizeof(buf), "inputbw", p)) {
587  s->inputbw = strtoll(buf, NULL, 10);
588  }
589  if (av_find_info_tag(buf, sizeof(buf), "oheadbw", p)) {
590  s->oheadbw = strtol(buf, NULL, 10);
591  }
592  if (av_find_info_tag(buf, sizeof(buf), "latency", p)) {
593  s->latency = strtoll(buf, NULL, 10);
594  }
595  if (av_find_info_tag(buf, sizeof(buf), "tsbpddelay", p)) {
596  s->latency = strtoll(buf, NULL, 10);
597  }
598  if (av_find_info_tag(buf, sizeof(buf), "rcvlatency", p)) {
599  s->rcvlatency = strtoll(buf, NULL, 10);
600  }
601  if (av_find_info_tag(buf, sizeof(buf), "peerlatency", p)) {
602  s->peerlatency = strtoll(buf, NULL, 10);
603  }
604  if (av_find_info_tag(buf, sizeof(buf), "tlpktdrop", p)) {
605  s->tlpktdrop = strtol(buf, NULL, 10);
606  }
607  if (av_find_info_tag(buf, sizeof(buf), "nakreport", p)) {
608  s->nakreport = strtol(buf, NULL, 10);
609  }
610  if (av_find_info_tag(buf, sizeof(buf), "connect_timeout", p)) {
611  s->connect_timeout = strtoll(buf, NULL, 10);
612  }
613  if (av_find_info_tag(buf, sizeof(buf), "payload_size", p) ||
614  av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
615  s->payload_size = strtol(buf, NULL, 10);
616  }
617  if (av_find_info_tag(buf, sizeof(buf), "mode", p)) {
618  if (!strcmp(buf, "caller")) {
619  s->mode = SRT_MODE_CALLER;
620  } else if (!strcmp(buf, "listener")) {
621  s->mode = SRT_MODE_LISTENER;
622  } else if (!strcmp(buf, "rendezvous")) {
623  s->mode = SRT_MODE_RENDEZVOUS;
624  } else {
625  ret = AVERROR(EINVAL);
626  goto err;
627  }
628  }
629  if (av_find_info_tag(buf, sizeof(buf), "sndbuf", p)) {
630  s->sndbuf = strtol(buf, NULL, 10);
631  }
632  if (av_find_info_tag(buf, sizeof(buf), "rcvbuf", p)) {
633  s->rcvbuf = strtol(buf, NULL, 10);
634  }
635  if (av_find_info_tag(buf, sizeof(buf), "lossmaxttl", p)) {
636  s->lossmaxttl = strtol(buf, NULL, 10);
637  }
638  if (av_find_info_tag(buf, sizeof(buf), "minversion", p)) {
639  s->minversion = strtol(buf, NULL, 0);
640  }
641  if (av_find_info_tag(buf, sizeof(buf), "streamid", p)) {
642  av_freep(&s->streamid);
643  s->streamid = ff_urldecode(buf, 1);
644  if (!s->streamid) {
645  ret = AVERROR(ENOMEM);
646  goto err;
647  }
648  }
649  if (av_find_info_tag(buf, sizeof(buf), "smoother", p)) {
650  av_freep(&s->smoother);
651  s->smoother = ff_urldecode(buf, 1);
652  if(!s->smoother) {
653  ret = AVERROR(ENOMEM);
654  goto err;
655  }
656  }
657  if (av_find_info_tag(buf, sizeof(buf), "messageapi", p)) {
658  s->messageapi = strtol(buf, NULL, 10);
659  }
660  if (av_find_info_tag(buf, sizeof(buf), "transtype", p)) {
661  if (!strcmp(buf, "live")) {
662  s->transtype = SRTT_LIVE;
663  } else if (!strcmp(buf, "file")) {
664  s->transtype = SRTT_FILE;
665  } else {
666  ret = AVERROR(EINVAL);
667  goto err;
668  }
669  }
670  if (av_find_info_tag(buf, sizeof(buf), "linger", p)) {
671  s->linger = strtol(buf, NULL, 10);
672  }
673  }
674  ret = libsrt_setup(h, uri, flags);
675  if (ret < 0)
676  goto err;
677  return 0;
678 
679 err:
680  srt_cleanup();
681  return ret;
682 }
683 
684 static int libsrt_read(URLContext *h, uint8_t *buf, int size)
685 {
686  SRTContext *s = h->priv_data;
687  int ret;
688 
689  if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
690  ret = libsrt_network_wait_fd_timeout(h, s->eid, 0, h->rw_timeout, &h->interrupt_callback);
691  if (ret)
692  return ret;
693  }
694 
695  ret = srt_recvmsg(s->fd, buf, size);
696  if (ret < 0) {
697  ret = libsrt_neterrno(h);
698  }
699 
700  return ret;
701 }
702 
703 static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
704 {
705  SRTContext *s = h->priv_data;
706  int ret;
707 
708  if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
709  ret = libsrt_network_wait_fd_timeout(h, s->eid, 1, h->rw_timeout, &h->interrupt_callback);
710  if (ret)
711  return ret;
712  }
713 
714  ret = srt_sendmsg(s->fd, buf, size, -1, 1);
715  if (ret < 0) {
716  ret = libsrt_neterrno(h);
717  }
718 
719  return ret;
720 }
721 
723 {
724  SRTContext *s = h->priv_data;
725 
726  srt_epoll_release(s->eid);
727  srt_close(s->fd);
728 
729  srt_cleanup();
730 
731  return 0;
732 }
733 
734 static const AVClass libsrt_class = {
735  .class_name = "libsrt",
736  .item_name = av_default_item_name,
737  .option = libsrt_options,
738  .version = LIBAVUTIL_VERSION_INT,
739 };
740 
742  .name = "srt",
743  .url_open = libsrt_open,
744  .url_read = libsrt_read,
745  .url_write = libsrt_write,
746  .url_close = libsrt_close,
747  .priv_data_size = sizeof(SRTContext),
749  .priv_data_class = &libsrt_class,
750 };
error
static void error(const char *err)
Definition: target_bsf_fuzzer.c:31
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:186
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:753
SRTContext::ffs
int ffs
Definition: libsrt.c:72
URL_PROTOCOL_FLAG_NETWORK
#define URL_PROTOCOL_FLAG_NETWORK
Definition: url.h:33
SRTContext::mode
enum SRTMode mode
Definition: libsrt.c:84
int64_t
long long int64_t
Definition: coverity.c:34
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:217
SRTContext::sndbuf
int sndbuf
Definition: libsrt.c:85
SRTContext
Definition: srtenc.c:34
AVOption
AVOption.
Definition: opt.h:346
SRTContext::pbkeylen
int pbkeylen
Definition: libsrt.c:63
AV_LOG_VERBOSE
#define AV_LOG_VERBOSE
Detailed information.
Definition: log.h:196
libsrt_getsockopt
static int libsrt_getsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char *optnamestr, void *optval, int *optlen)
Definition: libsrt.c:161
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:73
SRTContext::fd
int fd
Definition: libsrt.c:55
URLProtocol
Definition: url.h:51
D
#define D
Definition: libsrt.c:97
os_support.h
OFFSET
#define OFFSET(x)
Definition: libsrt.c:99
AVIOInterruptCB
Callback for checking whether to abort blocking functions.
Definition: avio.h:59
SRTContext::smoother
char * smoother
Definition: libsrt.c:90
SRT_MODE_LISTENER
@ SRT_MODE_LISTENER
Definition: libsrt.c:49
SRTContext::streamid
char * streamid
Definition: libsrt.c:89
freeaddrinfo
#define freeaddrinfo
Definition: network.h:218
SRTContext::listen_timeout
int64_t listen_timeout
Definition: libsrt.c:58
ff_urldecode
char * ff_urldecode(const char *url, int decode_plus_sign)
Decodes an URL from its percent-encoded form back into normal representation.
Definition: urldecode.c:35
SRTContext::eid
int eid
Definition: libsrt.c:56
fail
#define fail()
Definition: checkasm.h:179
SRTContext::ipttl
int ipttl
Definition: libsrt.c:73
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:193
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:853
SRTContext::oheadbw
int oheadbw
Definition: libsrt.c:76
libsrt_open
static int libsrt_open(URLContext *h, const char *uri, int flags)
Definition: libsrt.c:532
SRTContext::minversion
int minversion
Definition: libsrt.c:88
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:180
ff_libsrt_protocol
const URLProtocol ff_libsrt_protocol
Definition: libsrt.c:741
s
#define s(width, name)
Definition: cbs_vp9.c:198
libsrt_epoll_create
static int libsrt_epoll_create(URLContext *h, int fd, int write)
Definition: libsrt.c:180
libsrt_setsockopt
static int libsrt_setsockopt(URLContext *h, int fd, SRT_SOCKOPT optname, const char *optnamestr, const void *optval, int optlen)
Definition: libsrt.c:290
SRTContext::maxbw
int64_t maxbw
Definition: libsrt.c:62
AV_OPT_TYPE_INT64
@ AV_OPT_TYPE_INT64
Definition: opt.h:236
SRTContext::rcvlatency
int64_t rcvlatency
Definition: libsrt.c:82
AVIO_FLAG_WRITE
#define AVIO_FLAG_WRITE
write-only
Definition: avio.h:618
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
libsrt_options
static const AVOption libsrt_options[]
Definition: libsrt.c:100
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:237
libsrt_set_options_pre
static int libsrt_set_options_pre(URLContext *h, int fd)
Definition: libsrt.c:317
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:170
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:66
NULL
#define NULL
Definition: coverity.c:32
SRTContext::lossmaxttl
int lossmaxttl
Definition: libsrt.c:87
SRTContext::transtype
SRT_TRANSTYPE transtype
Definition: libsrt.c:92
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:237
parseutils.h
libsrt_set_options_post
static int libsrt_set_options_post(URLContext *h, int fd)
Definition: libsrt.c:303
time.h
addrinfo::ai_family
int ai_family
Definition: network.h:139
SRTContext::payload_size
int payload_size
Definition: libsrt.c:81
SRTContext::inputbw
int64_t inputbw
Definition: libsrt.c:75
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:121
size
int size
Definition: twinvq_data.h:10344
SRTContext::linger
int linger
Definition: libsrt.c:93
E
#define E
Definition: libsrt.c:98
URLProtocol::name
const char * name
Definition: url.h:52
libsrt_write
static int libsrt_write(URLContext *h, const uint8_t *buf, int size)
Definition: libsrt.c:703
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:35
modes
static const SiprModeParam modes[MODE_COUNT]
Definition: sipr.c:70
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:358
url.h
SRTContext::send_buffer_size
int send_buffer_size
Definition: libsrt.c:60
len
int len
Definition: vorbis_enc_data.h:426
int_cb
const AVIOInterruptCB int_cb
Definition: ffmpeg.c:328
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:71
addrinfo::ai_socktype
int ai_socktype
Definition: network.h:140
SRTContext::peerlatency
int64_t peerlatency
Definition: libsrt.c:83
SRTContext::passphrase
char * passphrase
Definition: libsrt.c:64
avformat.h
network.h
SRTContext::messageapi
int messageapi
Definition: libsrt.c:91
urldecode.h
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:235
libsrt_class
static const AVClass libsrt_class
Definition: libsrt.c:734
SRTContext::connect_timeout
int64_t connect_timeout
Definition: libsrt.c:80
libsrt_read
static int libsrt_read(URLContext *h, uint8_t *buf, int size)
Definition: libsrt.c:684
libsrt_setup
static int libsrt_setup(URLContext *h, const char *uri, int flags)
Definition: libsrt.c:383
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:269
libsrt_close
static int libsrt_close(URLContext *h)
Definition: libsrt.c:722
SRTContext::iptos
int iptos
Definition: libsrt.c:74
SRTContext::rcvbuf
int rcvbuf
Definition: libsrt.c:86
AV_OPT_TYPE_BOOL
@ AV_OPT_TYPE_BOOL
Definition: opt.h:251
SRTContext::latency
int64_t latency
Definition: libsrt.c:77
AVIO_FLAG_NONBLOCK
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
Definition: avio.h:636
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:34
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:79
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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:58
AV_OPT_TYPE_STRING
@ AV_OPT_TYPE_STRING
Definition: opt.h:239
addrinfo
Definition: network.h:137
libsrt_neterrno
static int libsrt_neterrno(URLContext *h)
Definition: libsrt.c:151
AV_OPT_TYPE_CONST
@ AV_OPT_TYPE_CONST
Definition: opt.h:244
snprintf
#define snprintf
Definition: snprintf.h:34
SRTMode
SRTMode
Definition: libsrt.c:47
SRTContext::mss
int mss
Definition: libsrt.c:71
AI_PASSIVE
#define AI_PASSIVE
Definition: network.h:179
SRTContext::tlpktdrop
int tlpktdrop
Definition: libsrt.c:78
SRTContext::tsbpd
int tsbpd
Definition: libsrt.c:94