37 #ifndef SRT_LIVE_DEFAULT_PAYLOAD_SIZE 
   38 #define SRT_LIVE_DEFAULT_PAYLOAD_SIZE 1316 
   42 #ifndef SRT_LIVE_MAX_PAYLOAD_SIZE 
   43 #define SRT_LIVE_MAX_PAYLOAD_SIZE 1456 
   64 #if SRT_VERSION_VALUE >= 0x010302 
   65     int enforced_encryption;
 
   96 #define D AV_OPT_FLAG_DECODING_PARAM 
   97 #define E AV_OPT_FLAG_ENCODING_PARAM 
   98 #define OFFSET(x) offsetof(SRTContext, x) 
  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 },
 
  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 },
 
  118     { 
"ffs",            
"Flight flag size (window size) (in bytes)",                            
OFFSET(ffs),              
AV_OPT_TYPE_INT,      { .i64 = -1 }, -1, INT_MAX,   .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" },
 
  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 },
 
  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" },
 
  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 },
 
  153     int err = srt_getlasterror(&os_errno);
 
  154     if (err == SRT_EASYNCRCV || err == SRT_EASYNCSND)
 
  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());
 
  171     int ret, blocking = enable ? 0 : 1;
 
  173     ret = srt_setsockopt(socket, 0, SRTO_SNDSYN, &blocking, 
sizeof(blocking));
 
  176     return srt_setsockopt(socket, 0, SRTO_RCVSYN, &blocking, 
sizeof(blocking));
 
  181     int modes = SRT_EPOLL_ERR | (write ? SRT_EPOLL_OUT : SRT_EPOLL_IN);
 
  182     int eid = srt_epoll_create();
 
  185     if (srt_epoll_add_usock(eid, fd, &
modes) < 0) {
 
  186         srt_epoll_release(eid);
 
  194     int ret, 
len = 1, errlen = 1;
 
  204         if (srt_getlasterror(
NULL) == SRT_ETIMEOUT)
 
  219     int64_t wait_start = 0;
 
  242     int streamid_len = 
sizeof(streamid);
 
  243     if (srt_setsockopt(fd, SOL_SOCKET, SRTO_REUSEADDR, &reuse, 
sizeof(reuse))) {
 
  246     if (srt_bind(fd, addr, addrlen))
 
  249     if (srt_listen(fd, 1))
 
  272     if (srt_connect(fd, addr, addrlen) < 0)
 
  279                    "Connection to %s failed (%s), trying next address\n",
 
  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());
 
  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)) {
 
  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;
 
  326     int connect_timeout = 
s->connect_timeout;
 
  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) ||
 
  338         (
s->enforced_encryption >= 0 && 
libsrt_setsockopt(
h, fd, SRTO_STRICTENC, 
"SRTO_STRICTENC", &
s->enforced_encryption, 
sizeof(
s->enforced_encryption)) < 0) ||
 
  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) ||
 
  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) ||
 
  362         (
s->smoother && 
libsrt_setsockopt(
h, fd, SRTO_SMOOTHER, 
"SRTO_SMOOTHER", 
s->smoother, strlen(
s->smoother)) < 0) ||
 
  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) ||
 
  367         (
s->tsbpd >= 0 && 
libsrt_setsockopt(
h, fd, SRTO_TSBPDMODE, 
"SRTO_TSBPDMODE", &
s->tsbpd, 
sizeof(
s->tsbpd)) < 0)) {
 
  371     if (
s->linger >= 0) {
 
  373         lin.l_linger = 
s->linger;
 
  374         lin.l_onoff  = lin.l_linger > 0 ? 1 : 0;
 
  384     struct addrinfo hints = { 0 }, *ai, *cur_ai;
 
  390     char hostname[1024],proto[1024],path[1024];
 
  392     int64_t open_timeout = 0;
 
  396         &port, path, 
sizeof(path), uri);
 
  397     if (strcmp(proto, 
"srt"))
 
  399     if (port <= 0 || port >= 65536) {
 
  403     p = strchr(uri, 
'?');
 
  406             s->rw_timeout = strtoll(buf, 
NULL, 10);
 
  409             s->listen_timeout = strtoll(buf, 
NULL, 10);
 
  412     if (
s->rw_timeout >= 0) {
 
  413         open_timeout = 
h->rw_timeout = 
s->rw_timeout;
 
  417     snprintf(portstr, 
sizeof(portstr), 
"%d", port);
 
  423                "Failed to resolve hostname %s: %s\n",
 
  432 #if SRT_VERSION_VALUE >= 0x010401 
  433     fd = srt_create_socket();
 
  435     fd = srt_socket(cur_ai->ai_family, cur_ai->ai_socktype, 0);
 
  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));
 
  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));
 
  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);
 
  470             if (srt_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) {
 
  472                 srt_epoll_release(write_eid);
 
  478                                     open_timeout, 
h, !!cur_ai->ai_next);
 
  479         srt_epoll_release(write_eid);
 
  493         int optlen = 
sizeof(packet_size);
 
  498             h->max_packet_size = packet_size;
 
  513     if (cur_ai->ai_next) {
 
  515         cur_ai = cur_ai->ai_next;
 
  535     if (srt_startup() < 0) {
 
  540     p = strchr(uri, 
'?');
 
  543             s->maxbw = strtoll(buf, 
NULL, 10);
 
  546             s->pbkeylen = strtol(buf, 
NULL, 10);
 
  552 #if SRT_VERSION_VALUE >= 0x010302 
  554             s->enforced_encryption = strtol(buf, 
NULL, 10);
 
  557             s->kmrefreshrate = strtol(buf, 
NULL, 10);
 
  560             s->kmpreannounce = strtol(buf, 
NULL, 10);
 
  563             s->snddropdelay = strtoll(buf, 
NULL, 10);
 
  567             s->mss = strtol(buf, 
NULL, 10);
 
  570             s->ffs = strtol(buf, 
NULL, 10);
 
  573             s->ipttl = strtol(buf, 
NULL, 10);
 
  576             s->iptos = strtol(buf, 
NULL, 10);
 
  579             s->inputbw = strtoll(buf, 
NULL, 10);
 
  582             s->oheadbw = strtol(buf, 
NULL, 10);
 
  585             s->latency = strtoll(buf, 
NULL, 10);
 
  588             s->latency = strtoll(buf, 
NULL, 10);
 
  591             s->rcvlatency = strtoll(buf, 
NULL, 10);
 
  594             s->peerlatency = strtoll(buf, 
NULL, 10);
 
  597             s->tlpktdrop = strtol(buf, 
NULL, 10);
 
  600             s->nakreport = strtol(buf, 
NULL, 10);
 
  603             s->connect_timeout = strtoll(buf, 
NULL, 10);
 
  607             s->payload_size = strtol(buf, 
NULL, 10);
 
  610             if (!strcmp(buf, 
"caller")) {
 
  612             } 
else if (!strcmp(buf, 
"listener")) {
 
  614             } 
else if (!strcmp(buf, 
"rendezvous")) {
 
  622             s->sndbuf = strtol(buf, 
NULL, 10);
 
  625             s->rcvbuf = strtol(buf, 
NULL, 10);
 
  628             s->lossmaxttl = strtol(buf, 
NULL, 10);
 
  631             s->minversion = strtol(buf, 
NULL, 0);
 
  650             s->messageapi = strtol(buf, 
NULL, 10);
 
  653             if (!strcmp(buf, 
"live")) {
 
  654                 s->transtype = SRTT_LIVE;
 
  655             } 
else if (!strcmp(buf, 
"file")) {
 
  656                 s->transtype = SRTT_FILE;
 
  663             s->linger = strtol(buf, 
NULL, 10);
 
  689     ret = srt_recvmsg(
s->fd, buf, 
size);
 
  708     ret = srt_sendmsg(
s->fd, buf, 
size, -1, 1);
 
  720     srt_epoll_release(
s->eid);