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