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