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