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