LCOV - code coverage report
Current view: top level - libavformat - udp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 0 517 0.0 %
Date: 2017-12-17 23:02:56 Functions: 0 20 0.0 %

          Line data    Source code
       1             : /*
       2             :  * UDP prototype streaming system
       3             :  * Copyright (c) 2000, 2001, 2002 Fabrice Bellard
       4             :  *
       5             :  * This file is part of FFmpeg.
       6             :  *
       7             :  * FFmpeg is free software; you can redistribute it and/or
       8             :  * modify it under the terms of the GNU Lesser General Public
       9             :  * License as published by the Free Software Foundation; either
      10             :  * version 2.1 of the License, or (at your option) any later version.
      11             :  *
      12             :  * FFmpeg is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
      15             :  * Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with FFmpeg; if not, write to the Free Software
      19             :  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
      20             :  */
      21             : 
      22             : /**
      23             :  * @file
      24             :  * UDP protocol
      25             :  */
      26             : 
      27             : #define _DEFAULT_SOURCE
      28             : #define _BSD_SOURCE     /* Needed for using struct ip_mreq with recent glibc */
      29             : 
      30             : #include "avformat.h"
      31             : #include "avio_internal.h"
      32             : #include "libavutil/avassert.h"
      33             : #include "libavutil/parseutils.h"
      34             : #include "libavutil/fifo.h"
      35             : #include "libavutil/intreadwrite.h"
      36             : #include "libavutil/avstring.h"
      37             : #include "libavutil/opt.h"
      38             : #include "libavutil/log.h"
      39             : #include "libavutil/time.h"
      40             : #include "internal.h"
      41             : #include "network.h"
      42             : #include "os_support.h"
      43             : #include "url.h"
      44             : 
      45             : #ifdef __APPLE__
      46             : #include "TargetConditionals.h"
      47             : #endif
      48             : 
      49             : #if HAVE_UDPLITE_H
      50             : #include "udplite.h"
      51             : #else
      52             : /* On many Linux systems, udplite.h is missing but the kernel supports UDP-Lite.
      53             :  * So, we provide a fallback here.
      54             :  */
      55             : #define UDPLITE_SEND_CSCOV                               10
      56             : #define UDPLITE_RECV_CSCOV                               11
      57             : #endif
      58             : 
      59             : #ifndef IPPROTO_UDPLITE
      60             : #define IPPROTO_UDPLITE                                  136
      61             : #endif
      62             : 
      63             : #if HAVE_PTHREAD_CANCEL
      64             : #include <pthread.h>
      65             : #endif
      66             : 
      67             : #ifndef IPV6_ADD_MEMBERSHIP
      68             : #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
      69             : #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
      70             : #endif
      71             : 
      72             : #define UDP_TX_BUF_SIZE 32768
      73             : #define UDP_MAX_PKT_SIZE 65536
      74             : #define UDP_HEADER_SIZE 8
      75             : 
      76             : typedef struct UDPContext {
      77             :     const AVClass *class;
      78             :     int udp_fd;
      79             :     int ttl;
      80             :     int udplite_coverage;
      81             :     int buffer_size;
      82             :     int pkt_size;
      83             :     int is_multicast;
      84             :     int is_broadcast;
      85             :     int local_port;
      86             :     int reuse_socket;
      87             :     int overrun_nonfatal;
      88             :     struct sockaddr_storage dest_addr;
      89             :     int dest_addr_len;
      90             :     int is_connected;
      91             : 
      92             :     /* Circular Buffer variables for use in UDP receive code */
      93             :     int circular_buffer_size;
      94             :     AVFifoBuffer *fifo;
      95             :     int circular_buffer_error;
      96             :     int64_t bitrate; /* number of bits to send per second */
      97             :     int64_t burst_bits;
      98             :     int close_req;
      99             : #if HAVE_PTHREAD_CANCEL
     100             :     pthread_t circular_buffer_thread;
     101             :     pthread_mutex_t mutex;
     102             :     pthread_cond_t cond;
     103             :     int thread_started;
     104             : #endif
     105             :     uint8_t tmp[UDP_MAX_PKT_SIZE+4];
     106             :     int remaining_in_dg;
     107             :     char *localaddr;
     108             :     int timeout;
     109             :     struct sockaddr_storage local_addr_storage;
     110             :     char *sources;
     111             :     char *block;
     112             : } UDPContext;
     113             : 
     114             : #define OFFSET(x) offsetof(UDPContext, x)
     115             : #define D AV_OPT_FLAG_DECODING_PARAM
     116             : #define E AV_OPT_FLAG_ENCODING_PARAM
     117             : static const AVOption options[] = {
     118             :     { "buffer_size",    "System data size (in bytes)",                     OFFSET(buffer_size),    AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
     119             :     { "bitrate",        "Bits to send per second",                         OFFSET(bitrate),        AV_OPT_TYPE_INT64,  { .i64 = 0  },     0, INT64_MAX, .flags = E },
     120             :     { "burst_bits",     "Max length of bursts in bits (when using bitrate)", OFFSET(burst_bits),   AV_OPT_TYPE_INT64,  { .i64 = 0  },     0, INT64_MAX, .flags = E },
     121             :     { "localport",      "Local port",                                      OFFSET(local_port),     AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, D|E },
     122             :     { "local_port",     "Local port",                                      OFFSET(local_port),     AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
     123             :     { "localaddr",      "Local address",                                   OFFSET(localaddr),      AV_OPT_TYPE_STRING, { .str = NULL },               .flags = D|E },
     124             :     { "udplite_coverage", "choose UDPLite head size which should be validated by checksum", OFFSET(udplite_coverage), AV_OPT_TYPE_INT, {.i64 = 0}, 0, INT_MAX, D|E },
     125             :     { "pkt_size",       "Maximum UDP packet size",                         OFFSET(pkt_size),       AV_OPT_TYPE_INT,    { .i64 = 1472 },  -1, INT_MAX, .flags = D|E },
     126             :     { "reuse",          "explicitly allow reusing UDP sockets",            OFFSET(reuse_socket),   AV_OPT_TYPE_BOOL,   { .i64 = -1 },    -1, 1,       D|E },
     127             :     { "reuse_socket",   "explicitly allow reusing UDP sockets",            OFFSET(reuse_socket),   AV_OPT_TYPE_BOOL,   { .i64 = -1 },    -1, 1,       .flags = D|E },
     128             :     { "broadcast", "explicitly allow or disallow broadcast destination",   OFFSET(is_broadcast),   AV_OPT_TYPE_BOOL,   { .i64 = 0  },     0, 1,       E },
     129             :     { "ttl",            "Time to live (multicast only)",                   OFFSET(ttl),            AV_OPT_TYPE_INT,    { .i64 = 16 },     0, INT_MAX, E },
     130             :     { "connect",        "set if connect() should be called on socket",     OFFSET(is_connected),   AV_OPT_TYPE_BOOL,   { .i64 =  0 },     0, 1,       .flags = D|E },
     131             :     { "fifo_size",      "set the UDP receiving circular buffer size, expressed as a number of packets with size of 188 bytes", OFFSET(circular_buffer_size), AV_OPT_TYPE_INT, {.i64 = 7*4096}, 0, INT_MAX, D },
     132             :     { "overrun_nonfatal", "survive in case of UDP receiving circular buffer overrun", OFFSET(overrun_nonfatal), AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1,    D },
     133             :     { "timeout",        "set raise error timeout (only in read mode)",     OFFSET(timeout),        AV_OPT_TYPE_INT,    { .i64 = 0 },      0, INT_MAX, D },
     134             :     { "sources",        "Source list",                                     OFFSET(sources),        AV_OPT_TYPE_STRING, { .str = NULL },               .flags = D|E },
     135             :     { "block",          "Block list",                                      OFFSET(block),          AV_OPT_TYPE_STRING, { .str = NULL },               .flags = D|E },
     136             :     { NULL }
     137             : };
     138             : 
     139             : static const AVClass udp_class = {
     140             :     .class_name = "udp",
     141             :     .item_name  = av_default_item_name,
     142             :     .option     = options,
     143             :     .version    = LIBAVUTIL_VERSION_INT,
     144             : };
     145             : 
     146             : static const AVClass udplite_context_class = {
     147             :     .class_name     = "udplite",
     148             :     .item_name      = av_default_item_name,
     149             :     .option         = options,
     150             :     .version        = LIBAVUTIL_VERSION_INT,
     151             : };
     152             : 
     153           0 : static void log_net_error(void *ctx, int level, const char* prefix)
     154             : {
     155             :     char errbuf[100];
     156           0 :     av_strerror(ff_neterrno(), errbuf, sizeof(errbuf));
     157           0 :     av_log(ctx, level, "%s: %s\n", prefix, errbuf);
     158           0 : }
     159             : 
     160           0 : static int udp_set_multicast_ttl(int sockfd, int mcastTTL,
     161             :                                  struct sockaddr *addr)
     162             : {
     163             : #ifdef IP_MULTICAST_TTL
     164           0 :     if (addr->sa_family == AF_INET) {
     165           0 :         if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) {
     166           0 :             log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL)");
     167           0 :             return -1;
     168             :         }
     169             :     }
     170             : #endif
     171             : #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS)
     172           0 :     if (addr->sa_family == AF_INET6) {
     173           0 :         if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) {
     174           0 :             log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS)");
     175           0 :             return -1;
     176             :         }
     177             :     }
     178             : #endif
     179           0 :     return 0;
     180             : }
     181             : 
     182           0 : static int udp_join_multicast_group(int sockfd, struct sockaddr *addr,struct sockaddr *local_addr)
     183             : {
     184             : #ifdef IP_ADD_MEMBERSHIP
     185           0 :     if (addr->sa_family == AF_INET) {
     186             :         struct ip_mreq mreq;
     187             : 
     188           0 :         mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
     189           0 :         if (local_addr)
     190           0 :             mreq.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr;
     191             :         else
     192           0 :             mreq.imr_interface.s_addr= INADDR_ANY;
     193           0 :         if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
     194           0 :             log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP)");
     195           0 :             return -1;
     196             :         }
     197             :     }
     198             : #endif
     199             : #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
     200           0 :     if (addr->sa_family == AF_INET6) {
     201             :         struct ipv6_mreq mreq6;
     202             : 
     203           0 :         memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
     204           0 :         mreq6.ipv6mr_interface= 0;
     205           0 :         if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
     206           0 :             log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP)");
     207           0 :             return -1;
     208             :         }
     209             :     }
     210             : #endif
     211           0 :     return 0;
     212             : }
     213             : 
     214           0 : static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr,struct sockaddr *local_addr)
     215             : {
     216             : #ifdef IP_DROP_MEMBERSHIP
     217           0 :     if (addr->sa_family == AF_INET) {
     218             :         struct ip_mreq mreq;
     219             : 
     220           0 :         mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
     221           0 :         if (local_addr)
     222           0 :             mreq.imr_interface= ((struct sockaddr_in *)local_addr)->sin_addr;
     223             :         else
     224           0 :             mreq.imr_interface.s_addr= INADDR_ANY;
     225           0 :         if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) {
     226           0 :             log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP)");
     227           0 :             return -1;
     228             :         }
     229             :     }
     230             : #endif
     231             : #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6)
     232           0 :     if (addr->sa_family == AF_INET6) {
     233             :         struct ipv6_mreq mreq6;
     234             : 
     235           0 :         memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr));
     236           0 :         mreq6.ipv6mr_interface= 0;
     237           0 :         if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) {
     238           0 :             log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP)");
     239           0 :             return -1;
     240             :         }
     241             :     }
     242             : #endif
     243           0 :     return 0;
     244             : }
     245             : 
     246           0 : static struct addrinfo *udp_resolve_host(URLContext *h,
     247             :                                          const char *hostname, int port,
     248             :                                          int type, int family, int flags)
     249             : {
     250           0 :     struct addrinfo hints = { 0 }, *res = 0;
     251             :     int error;
     252             :     char sport[16];
     253           0 :     const char *node = 0, *service = "0";
     254             : 
     255           0 :     if (port > 0) {
     256           0 :         snprintf(sport, sizeof(sport), "%d", port);
     257           0 :         service = sport;
     258             :     }
     259           0 :     if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) {
     260           0 :         node = hostname;
     261             :     }
     262           0 :     hints.ai_socktype = type;
     263           0 :     hints.ai_family   = family;
     264           0 :     hints.ai_flags = flags;
     265           0 :     if ((error = getaddrinfo(node, service, &hints, &res))) {
     266           0 :         res = NULL;
     267           0 :         av_log(h, AV_LOG_ERROR, "getaddrinfo(%s, %s): %s\n",
     268             :                node ? node : "unknown",
     269             :                service,
     270             :                gai_strerror(error));
     271             :     }
     272             : 
     273           0 :     return res;
     274             : }
     275             : 
     276           0 : static int udp_set_multicast_sources(URLContext *h,
     277             :                                      int sockfd, struct sockaddr *addr,
     278             :                                      int addr_len, char **sources,
     279             :                                      int nb_sources, int include)
     280             : {
     281             : #if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32) && (!defined(TARGET_OS_TV) || !TARGET_OS_TV)
     282             :     /* These ones are available in the microsoft SDK, but don't seem to work
     283             :      * as on linux, so just prefer the v4-only approach there for now. */
     284             :     int i;
     285           0 :     for (i = 0; i < nb_sources; i++) {
     286             :         struct group_source_req mreqs;
     287           0 :         int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
     288           0 :         struct addrinfo *sourceaddr = udp_resolve_host(h, sources[i], 0,
     289             :                                                        SOCK_DGRAM, AF_UNSPEC,
     290             :                                                        0);
     291           0 :         if (!sourceaddr)
     292           0 :             return AVERROR(ENOENT);
     293             : 
     294           0 :         mreqs.gsr_interface = 0;
     295           0 :         memcpy(&mreqs.gsr_group, addr, addr_len);
     296           0 :         memcpy(&mreqs.gsr_source, sourceaddr->ai_addr, sourceaddr->ai_addrlen);
     297           0 :         freeaddrinfo(sourceaddr);
     298             : 
     299           0 :         if (setsockopt(sockfd, level,
     300             :                        include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
     301             :                        (const void *)&mreqs, sizeof(mreqs)) < 0) {
     302           0 :             if (include)
     303           0 :                 log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_JOIN_SOURCE_GROUP)");
     304             :             else
     305           0 :                 log_net_error(NULL, AV_LOG_ERROR, "setsockopt(MCAST_BLOCK_SOURCE)");
     306           0 :             return ff_neterrno();
     307             :         }
     308             :     }
     309             : #elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE)
     310             :     int i;
     311             :     if (addr->sa_family != AF_INET) {
     312             :         av_log(NULL, AV_LOG_ERROR,
     313             :                "Setting multicast sources only supported for IPv4\n");
     314             :         return AVERROR(EINVAL);
     315             :     }
     316             :     for (i = 0; i < nb_sources; i++) {
     317             :         struct ip_mreq_source mreqs;
     318             :         struct addrinfo *sourceaddr = udp_resolve_host(h, sources[i], 0,
     319             :                                                        SOCK_DGRAM, AF_UNSPEC,
     320             :                                                        0);
     321             :         if (!sourceaddr)
     322             :             return AVERROR(ENOENT);
     323             :         if (sourceaddr->ai_addr->sa_family != AF_INET) {
     324             :             freeaddrinfo(sourceaddr);
     325             :             av_log(NULL, AV_LOG_ERROR, "%s is of incorrect protocol family\n",
     326             :                    sources[i]);
     327             :             return AVERROR(EINVAL);
     328             :         }
     329             : 
     330             :         mreqs.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr;
     331             :         mreqs.imr_interface.s_addr = INADDR_ANY;
     332             :         mreqs.imr_sourceaddr.s_addr = ((struct sockaddr_in *)sourceaddr->ai_addr)->sin_addr.s_addr;
     333             :         freeaddrinfo(sourceaddr);
     334             : 
     335             :         if (setsockopt(sockfd, IPPROTO_IP,
     336             :                        include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
     337             :                        (const void *)&mreqs, sizeof(mreqs)) < 0) {
     338             :             if (include)
     339             :                 log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_SOURCE_MEMBERSHIP)");
     340             :             else
     341             :                 log_net_error(NULL, AV_LOG_ERROR, "setsockopt(IP_BLOCK_SOURCE)");
     342             :             return ff_neterrno();
     343             :         }
     344             :     }
     345             : #else
     346             :     return AVERROR(ENOSYS);
     347             : #endif
     348           0 :     return 0;
     349             : }
     350           0 : static int udp_set_url(URLContext *h,
     351             :                        struct sockaddr_storage *addr,
     352             :                        const char *hostname, int port)
     353             : {
     354             :     struct addrinfo *res0;
     355             :     int addr_len;
     356             : 
     357           0 :     res0 = udp_resolve_host(h, hostname, port, SOCK_DGRAM, AF_UNSPEC, 0);
     358           0 :     if (!res0) return AVERROR(EIO);
     359           0 :     memcpy(addr, res0->ai_addr, res0->ai_addrlen);
     360           0 :     addr_len = res0->ai_addrlen;
     361           0 :     freeaddrinfo(res0);
     362             : 
     363           0 :     return addr_len;
     364             : }
     365             : 
     366           0 : static int udp_socket_create(URLContext *h, struct sockaddr_storage *addr,
     367             :                              socklen_t *addr_len, const char *localaddr)
     368             : {
     369           0 :     UDPContext *s = h->priv_data;
     370           0 :     int udp_fd = -1;
     371             :     struct addrinfo *res0, *res;
     372           0 :     int family = AF_UNSPEC;
     373             : 
     374           0 :     if (((struct sockaddr *) &s->dest_addr)->sa_family)
     375           0 :         family = ((struct sockaddr *) &s->dest_addr)->sa_family;
     376           0 :     res0 = udp_resolve_host(h, (localaddr && localaddr[0]) ? localaddr : NULL,
     377             :                             s->local_port,
     378             :                             SOCK_DGRAM, family, AI_PASSIVE);
     379           0 :     if (!res0)
     380           0 :         goto fail;
     381           0 :     for (res = res0; res; res=res->ai_next) {
     382           0 :         if (s->udplite_coverage)
     383           0 :             udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, IPPROTO_UDPLITE);
     384             :         else
     385           0 :             udp_fd = ff_socket(res->ai_family, SOCK_DGRAM, 0);
     386           0 :         if (udp_fd != -1) break;
     387           0 :         log_net_error(NULL, AV_LOG_ERROR, "socket");
     388             :     }
     389             : 
     390           0 :     if (udp_fd < 0)
     391           0 :         goto fail;
     392             : 
     393           0 :     memcpy(addr, res->ai_addr, res->ai_addrlen);
     394           0 :     *addr_len = res->ai_addrlen;
     395             : 
     396           0 :     freeaddrinfo(res0);
     397             : 
     398           0 :     return udp_fd;
     399             : 
     400           0 :  fail:
     401           0 :     if (udp_fd >= 0)
     402           0 :         closesocket(udp_fd);
     403           0 :     if(res0)
     404           0 :         freeaddrinfo(res0);
     405           0 :     return -1;
     406             : }
     407             : 
     408           0 : static int udp_port(struct sockaddr_storage *addr, int addr_len)
     409             : {
     410             :     char sbuf[sizeof(int)*3+1];
     411             :     int error;
     412             : 
     413           0 :     if ((error = getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0,  sbuf, sizeof(sbuf), NI_NUMERICSERV)) != 0) {
     414           0 :         av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", gai_strerror(error));
     415           0 :         return -1;
     416             :     }
     417             : 
     418           0 :     return strtol(sbuf, NULL, 10);
     419             : }
     420             : 
     421             : 
     422             : /**
     423             :  * If no filename is given to av_open_input_file because you want to
     424             :  * get the local port first, then you must call this function to set
     425             :  * the remote server address.
     426             :  *
     427             :  * url syntax: udp://host:port[?option=val...]
     428             :  * option: 'ttl=n'       : set the ttl value (for multicast only)
     429             :  *         'localport=n' : set the local port
     430             :  *         'pkt_size=n'  : set max packet size
     431             :  *         'reuse=1'     : enable reusing the socket
     432             :  *         'overrun_nonfatal=1': survive in case of circular buffer overrun
     433             :  *
     434             :  * @param h media file context
     435             :  * @param uri of the remote server
     436             :  * @return zero if no error.
     437             :  */
     438           0 : int ff_udp_set_remote_url(URLContext *h, const char *uri)
     439             : {
     440           0 :     UDPContext *s = h->priv_data;
     441             :     char hostname[256], buf[10];
     442             :     int port;
     443             :     const char *p;
     444             : 
     445           0 :     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
     446             : 
     447             :     /* set the destination address */
     448           0 :     s->dest_addr_len = udp_set_url(h, &s->dest_addr, hostname, port);
     449           0 :     if (s->dest_addr_len < 0) {
     450           0 :         return AVERROR(EIO);
     451             :     }
     452           0 :     s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr);
     453           0 :     p = strchr(uri, '?');
     454           0 :     if (p) {
     455           0 :         if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
     456           0 :             int was_connected = s->is_connected;
     457           0 :             s->is_connected = strtol(buf, NULL, 10);
     458           0 :             if (s->is_connected && !was_connected) {
     459           0 :                 if (connect(s->udp_fd, (struct sockaddr *) &s->dest_addr,
     460           0 :                             s->dest_addr_len)) {
     461           0 :                     s->is_connected = 0;
     462           0 :                     log_net_error(h, AV_LOG_ERROR, "connect");
     463           0 :                     return AVERROR(EIO);
     464             :                 }
     465             :             }
     466             :         }
     467             :     }
     468             : 
     469           0 :     return 0;
     470             : }
     471             : 
     472             : /**
     473             :  * Return the local port used by the UDP connection
     474             :  * @param h media file context
     475             :  * @return the local port number
     476             :  */
     477           0 : int ff_udp_get_local_port(URLContext *h)
     478             : {
     479           0 :     UDPContext *s = h->priv_data;
     480           0 :     return s->local_port;
     481             : }
     482             : 
     483             : /**
     484             :  * Return the udp file handle for select() usage to wait for several RTP
     485             :  * streams at the same time.
     486             :  * @param h media file context
     487             :  */
     488           0 : static int udp_get_file_handle(URLContext *h)
     489             : {
     490           0 :     UDPContext *s = h->priv_data;
     491           0 :     return s->udp_fd;
     492             : }
     493             : 
     494             : #if HAVE_PTHREAD_CANCEL
     495           0 : static void *circular_buffer_task_rx( void *_URLContext)
     496             : {
     497           0 :     URLContext *h = _URLContext;
     498           0 :     UDPContext *s = h->priv_data;
     499             :     int old_cancelstate;
     500             : 
     501           0 :     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
     502           0 :     pthread_mutex_lock(&s->mutex);
     503           0 :     if (ff_socket_nonblock(s->udp_fd, 0) < 0) {
     504           0 :         av_log(h, AV_LOG_ERROR, "Failed to set blocking mode");
     505           0 :         s->circular_buffer_error = AVERROR(EIO);
     506           0 :         goto end;
     507             :     }
     508           0 :     while(1) {
     509             :         int len;
     510             : 
     511           0 :         pthread_mutex_unlock(&s->mutex);
     512             :         /* Blocking operations are always cancellation points;
     513             :            see "General Information" / "Thread Cancelation Overview"
     514             :            in Single Unix. */
     515           0 :         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
     516           0 :         len = recv(s->udp_fd, s->tmp+4, sizeof(s->tmp)-4, 0);
     517           0 :         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
     518           0 :         pthread_mutex_lock(&s->mutex);
     519           0 :         if (len < 0) {
     520           0 :             if (ff_neterrno() != AVERROR(EAGAIN) && ff_neterrno() != AVERROR(EINTR)) {
     521           0 :                 s->circular_buffer_error = ff_neterrno();
     522           0 :                 goto end;
     523             :             }
     524           0 :             continue;
     525             :         }
     526           0 :         AV_WL32(s->tmp, len);
     527             : 
     528           0 :         if(av_fifo_space(s->fifo) < len + 4) {
     529             :             /* No Space left */
     530           0 :             if (s->overrun_nonfatal) {
     531           0 :                 av_log(h, AV_LOG_WARNING, "Circular buffer overrun. "
     532             :                         "Surviving due to overrun_nonfatal option\n");
     533           0 :                 continue;
     534             :             } else {
     535           0 :                 av_log(h, AV_LOG_ERROR, "Circular buffer overrun. "
     536             :                         "To avoid, increase fifo_size URL option. "
     537             :                         "To survive in such case, use overrun_nonfatal option\n");
     538           0 :                 s->circular_buffer_error = AVERROR(EIO);
     539           0 :                 goto end;
     540             :             }
     541             :         }
     542           0 :         av_fifo_generic_write(s->fifo, s->tmp, len+4, NULL);
     543           0 :         pthread_cond_signal(&s->cond);
     544             :     }
     545             : 
     546           0 : end:
     547           0 :     pthread_cond_signal(&s->cond);
     548           0 :     pthread_mutex_unlock(&s->mutex);
     549           0 :     return NULL;
     550             : }
     551             : 
     552           0 : static void *circular_buffer_task_tx( void *_URLContext)
     553             : {
     554           0 :     URLContext *h = _URLContext;
     555           0 :     UDPContext *s = h->priv_data;
     556             :     int old_cancelstate;
     557           0 :     int64_t target_timestamp = av_gettime_relative();
     558           0 :     int64_t start_timestamp = av_gettime_relative();
     559           0 :     int64_t sent_bits = 0;
     560           0 :     int64_t burst_interval = s->bitrate ? (s->burst_bits * 1000000 / s->bitrate) : 0;
     561           0 :     int64_t max_delay = s->bitrate ?  ((int64_t)h->max_packet_size * 8 * 1000000 / s->bitrate + 1) : 0;
     562             : 
     563           0 :     pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
     564           0 :     pthread_mutex_lock(&s->mutex);
     565             : 
     566           0 :     if (ff_socket_nonblock(s->udp_fd, 0) < 0) {
     567           0 :         av_log(h, AV_LOG_ERROR, "Failed to set blocking mode");
     568           0 :         s->circular_buffer_error = AVERROR(EIO);
     569           0 :         goto end;
     570             :     }
     571             : 
     572           0 :     for(;;) {
     573             :         int len;
     574             :         const uint8_t *p;
     575             :         uint8_t tmp[4];
     576             :         int64_t timestamp;
     577             : 
     578           0 :         len=av_fifo_size(s->fifo);
     579             : 
     580           0 :         while (len<4) {
     581           0 :             if (s->close_req)
     582           0 :                 goto end;
     583           0 :             if (pthread_cond_wait(&s->cond, &s->mutex) < 0) {
     584           0 :                 goto end;
     585             :             }
     586           0 :             len=av_fifo_size(s->fifo);
     587             :         }
     588             : 
     589           0 :         av_fifo_generic_read(s->fifo, tmp, 4, NULL);
     590           0 :         len=AV_RL32(tmp);
     591             : 
     592           0 :         av_assert0(len >= 0);
     593           0 :         av_assert0(len <= sizeof(s->tmp));
     594             : 
     595           0 :         av_fifo_generic_read(s->fifo, s->tmp, len, NULL);
     596             : 
     597           0 :         pthread_mutex_unlock(&s->mutex);
     598           0 :         pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_cancelstate);
     599             : 
     600           0 :         if (s->bitrate) {
     601           0 :             timestamp = av_gettime_relative();
     602           0 :             if (timestamp < target_timestamp) {
     603           0 :                 int64_t delay = target_timestamp - timestamp;
     604           0 :                 if (delay > max_delay) {
     605           0 :                     delay = max_delay;
     606           0 :                     start_timestamp = timestamp + delay;
     607           0 :                     sent_bits = 0;
     608             :                 }
     609           0 :                 av_usleep(delay);
     610             :             } else {
     611           0 :                 if (timestamp - burst_interval > target_timestamp) {
     612           0 :                     start_timestamp = timestamp - burst_interval;
     613           0 :                     sent_bits = 0;
     614             :                 }
     615             :             }
     616           0 :             sent_bits += len * 8;
     617           0 :             target_timestamp = start_timestamp + sent_bits * 1000000 / s->bitrate;
     618             :         }
     619             : 
     620           0 :         p = s->tmp;
     621           0 :         while (len) {
     622             :             int ret;
     623           0 :             av_assert0(len > 0);
     624           0 :             if (!s->is_connected) {
     625           0 :                 ret = sendto (s->udp_fd, p, len, 0,
     626           0 :                             (struct sockaddr *) &s->dest_addr,
     627           0 :                             s->dest_addr_len);
     628             :             } else
     629           0 :                 ret = send(s->udp_fd, p, len, 0);
     630           0 :             if (ret >= 0) {
     631           0 :                 len -= ret;
     632           0 :                 p   += ret;
     633             :             } else {
     634           0 :                 ret = ff_neterrno();
     635           0 :                 if (ret != AVERROR(EAGAIN) && ret != AVERROR(EINTR)) {
     636           0 :                     pthread_mutex_lock(&s->mutex);
     637           0 :                     s->circular_buffer_error = ret;
     638           0 :                     pthread_mutex_unlock(&s->mutex);
     639           0 :                     return NULL;
     640             :                 }
     641             :             }
     642             :         }
     643             : 
     644           0 :         pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_cancelstate);
     645           0 :         pthread_mutex_lock(&s->mutex);
     646             :     }
     647             : 
     648           0 : end:
     649           0 :     pthread_mutex_unlock(&s->mutex);
     650           0 :     return NULL;
     651             : }
     652             : 
     653             : 
     654             : #endif
     655             : 
     656           0 : static int parse_source_list(char *buf, char **sources, int *num_sources,
     657             :                              int max_sources)
     658             : {
     659             :     char *source_start;
     660             : 
     661           0 :     source_start = buf;
     662           0 :     while (1) {
     663           0 :         char *next = strchr(source_start, ',');
     664           0 :         if (next)
     665           0 :             *next = '\0';
     666           0 :         sources[*num_sources] = av_strdup(source_start);
     667           0 :         if (!sources[*num_sources])
     668           0 :             return AVERROR(ENOMEM);
     669           0 :         source_start = next + 1;
     670           0 :         (*num_sources)++;
     671           0 :         if (*num_sources >= max_sources || !next)
     672             :             break;
     673             :     }
     674           0 :     return 0;
     675             : }
     676             : 
     677             : /* put it in UDP context */
     678             : /* return non zero if error */
     679           0 : static int udp_open(URLContext *h, const char *uri, int flags)
     680             : {
     681           0 :     char hostname[1024], localaddr[1024] = "";
     682           0 :     int port, udp_fd = -1, tmp, bind_ret = -1, dscp = -1;
     683           0 :     UDPContext *s = h->priv_data;
     684             :     int is_output;
     685             :     const char *p;
     686             :     char buf[256];
     687             :     struct sockaddr_storage my_addr;
     688             :     socklen_t len;
     689           0 :     int i, num_include_sources = 0, num_exclude_sources = 0;
     690             :     char *include_sources[32], *exclude_sources[32];
     691             : 
     692           0 :     h->is_streamed = 1;
     693             : 
     694           0 :     is_output = !(flags & AVIO_FLAG_READ);
     695           0 :     if (s->buffer_size < 0)
     696           0 :         s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE;
     697             : 
     698           0 :     if (s->sources) {
     699           0 :         if (parse_source_list(s->sources, include_sources,
     700             :                               &num_include_sources,
     701             :                               FF_ARRAY_ELEMS(include_sources)))
     702           0 :             goto fail;
     703             :     }
     704             : 
     705           0 :     if (s->block) {
     706           0 :         if (parse_source_list(s->block, exclude_sources, &num_exclude_sources,
     707             :                               FF_ARRAY_ELEMS(exclude_sources)))
     708           0 :             goto fail;
     709             :     }
     710             : 
     711           0 :     if (s->pkt_size > 0)
     712           0 :         h->max_packet_size = s->pkt_size;
     713             : 
     714           0 :     p = strchr(uri, '?');
     715           0 :     if (p) {
     716           0 :         if (av_find_info_tag(buf, sizeof(buf), "reuse", p)) {
     717           0 :             char *endptr = NULL;
     718           0 :             s->reuse_socket = strtol(buf, &endptr, 10);
     719             :             /* assume if no digits were found it is a request to enable it */
     720           0 :             if (buf == endptr)
     721           0 :                 s->reuse_socket = 1;
     722             :         }
     723           0 :         if (av_find_info_tag(buf, sizeof(buf), "overrun_nonfatal", p)) {
     724           0 :             char *endptr = NULL;
     725           0 :             s->overrun_nonfatal = strtol(buf, &endptr, 10);
     726             :             /* assume if no digits were found it is a request to enable it */
     727           0 :             if (buf == endptr)
     728           0 :                 s->overrun_nonfatal = 1;
     729             :             if (!HAVE_PTHREAD_CANCEL)
     730             :                 av_log(h, AV_LOG_WARNING,
     731             :                        "'overrun_nonfatal' option was set but it is not supported "
     732             :                        "on this build (pthread support is required)\n");
     733             :         }
     734           0 :         if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
     735           0 :             s->ttl = strtol(buf, NULL, 10);
     736             :         }
     737           0 :         if (av_find_info_tag(buf, sizeof(buf), "udplite_coverage", p)) {
     738           0 :             s->udplite_coverage = strtol(buf, NULL, 10);
     739             :         }
     740           0 :         if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
     741           0 :             s->local_port = strtol(buf, NULL, 10);
     742             :         }
     743           0 :         if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
     744           0 :             s->pkt_size = strtol(buf, NULL, 10);
     745             :         }
     746           0 :         if (av_find_info_tag(buf, sizeof(buf), "buffer_size", p)) {
     747           0 :             s->buffer_size = strtol(buf, NULL, 10);
     748             :         }
     749           0 :         if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
     750           0 :             s->is_connected = strtol(buf, NULL, 10);
     751             :         }
     752           0 :         if (av_find_info_tag(buf, sizeof(buf), "dscp", p)) {
     753           0 :             dscp = strtol(buf, NULL, 10);
     754             :         }
     755           0 :         if (av_find_info_tag(buf, sizeof(buf), "fifo_size", p)) {
     756           0 :             s->circular_buffer_size = strtol(buf, NULL, 10);
     757             :             if (!HAVE_PTHREAD_CANCEL)
     758             :                 av_log(h, AV_LOG_WARNING,
     759             :                        "'circular_buffer_size' option was set but it is not supported "
     760             :                        "on this build (pthread support is required)\n");
     761             :         }
     762           0 :         if (av_find_info_tag(buf, sizeof(buf), "bitrate", p)) {
     763           0 :             s->bitrate = strtoll(buf, NULL, 10);
     764             :             if (!HAVE_PTHREAD_CANCEL)
     765             :                 av_log(h, AV_LOG_WARNING,
     766             :                        "'bitrate' option was set but it is not supported "
     767             :                        "on this build (pthread support is required)\n");
     768             :         }
     769           0 :         if (av_find_info_tag(buf, sizeof(buf), "burst_bits", p)) {
     770           0 :             s->burst_bits = strtoll(buf, NULL, 10);
     771             :         }
     772           0 :         if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) {
     773           0 :             av_strlcpy(localaddr, buf, sizeof(localaddr));
     774             :         }
     775           0 :         if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
     776           0 :             if (parse_source_list(buf, include_sources, &num_include_sources,
     777             :                                   FF_ARRAY_ELEMS(include_sources)))
     778           0 :                 goto fail;
     779             :         }
     780           0 :         if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
     781           0 :             if (parse_source_list(buf, exclude_sources, &num_exclude_sources,
     782             :                                   FF_ARRAY_ELEMS(exclude_sources)))
     783           0 :                 goto fail;
     784             :         }
     785           0 :         if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p))
     786           0 :             s->timeout = strtol(buf, NULL, 10);
     787           0 :         if (is_output && av_find_info_tag(buf, sizeof(buf), "broadcast", p))
     788           0 :             s->is_broadcast = strtol(buf, NULL, 10);
     789             :     }
     790             :     /* handling needed to support options picking from both AVOption and URL */
     791           0 :     s->circular_buffer_size *= 188;
     792           0 :     if (flags & AVIO_FLAG_WRITE) {
     793           0 :         h->max_packet_size = s->pkt_size;
     794             :     } else {
     795           0 :         h->max_packet_size = UDP_MAX_PKT_SIZE;
     796             :     }
     797           0 :     h->rw_timeout = s->timeout;
     798             : 
     799             :     /* fill the dest addr */
     800           0 :     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri);
     801             : 
     802             :     /* XXX: fix av_url_split */
     803           0 :     if (hostname[0] == '\0' || hostname[0] == '?') {
     804             :         /* only accepts null hostname if input */
     805           0 :         if (!(flags & AVIO_FLAG_READ))
     806           0 :             goto fail;
     807             :     } else {
     808           0 :         if (ff_udp_set_remote_url(h, uri) < 0)
     809           0 :             goto fail;
     810             :     }
     811             : 
     812           0 :     if ((s->is_multicast || s->local_port <= 0) && (h->flags & AVIO_FLAG_READ))
     813           0 :         s->local_port = port;
     814             : 
     815           0 :     if (localaddr[0])
     816           0 :         udp_fd = udp_socket_create(h, &my_addr, &len, localaddr);
     817             :     else
     818           0 :         udp_fd = udp_socket_create(h, &my_addr, &len, s->localaddr);
     819           0 :     if (udp_fd < 0)
     820           0 :         goto fail;
     821             : 
     822           0 :     s->local_addr_storage=my_addr; //store for future multicast join
     823             : 
     824             :     /* Follow the requested reuse option, unless it's multicast in which
     825             :      * case enable reuse unless explicitly disabled.
     826             :      */
     827           0 :     if (s->reuse_socket > 0 || (s->is_multicast && s->reuse_socket < 0)) {
     828           0 :         s->reuse_socket = 1;
     829           0 :         if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0)
     830           0 :             goto fail;
     831             :     }
     832             : 
     833           0 :     if (s->is_broadcast) {
     834             : #ifdef SO_BROADCAST
     835           0 :         if (setsockopt (udp_fd, SOL_SOCKET, SO_BROADCAST, &(s->is_broadcast), sizeof(s->is_broadcast)) != 0)
     836             : #endif
     837           0 :            goto fail;
     838             :     }
     839             : 
     840             :     /* Set the checksum coverage for UDP-Lite (RFC 3828) for sending and receiving.
     841             :      * The receiver coverage has to be less than or equal to the sender coverage.
     842             :      * Otherwise, the receiver will drop all packets.
     843             :      */
     844           0 :     if (s->udplite_coverage) {
     845           0 :         if (setsockopt (udp_fd, IPPROTO_UDPLITE, UDPLITE_SEND_CSCOV, &(s->udplite_coverage), sizeof(s->udplite_coverage)) != 0)
     846           0 :             av_log(h, AV_LOG_WARNING, "socket option UDPLITE_SEND_CSCOV not available");
     847             : 
     848           0 :         if (setsockopt (udp_fd, IPPROTO_UDPLITE, UDPLITE_RECV_CSCOV, &(s->udplite_coverage), sizeof(s->udplite_coverage)) != 0)
     849           0 :             av_log(h, AV_LOG_WARNING, "socket option UDPLITE_RECV_CSCOV not available");
     850             :     }
     851             : 
     852           0 :     if (dscp >= 0) {
     853           0 :         dscp <<= 2;
     854           0 :         if (setsockopt (udp_fd, IPPROTO_IP, IP_TOS, &dscp, sizeof(dscp)) != 0)
     855           0 :             goto fail;
     856             :     }
     857             : 
     858             :     /* If multicast, try binding the multicast address first, to avoid
     859             :      * receiving UDP packets from other sources aimed at the same UDP
     860             :      * port. This fails on windows. This makes sending to the same address
     861             :      * using sendto() fail, so only do it if we're opened in read-only mode. */
     862           0 :     if (s->is_multicast && !(h->flags & AVIO_FLAG_WRITE)) {
     863           0 :         bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len);
     864             :     }
     865             :     /* bind to the local address if not multicast or if the multicast
     866             :      * bind failed */
     867             :     /* the bind is needed to give a port to the socket now */
     868           0 :     if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) {
     869           0 :         log_net_error(h, AV_LOG_ERROR, "bind failed");
     870           0 :         goto fail;
     871             :     }
     872             : 
     873           0 :     len = sizeof(my_addr);
     874           0 :     getsockname(udp_fd, (struct sockaddr *)&my_addr, &len);
     875           0 :     s->local_port = udp_port(&my_addr, len);
     876             : 
     877           0 :     if (s->is_multicast) {
     878           0 :         if (h->flags & AVIO_FLAG_WRITE) {
     879             :             /* output */
     880           0 :             if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0)
     881           0 :                 goto fail;
     882             :         }
     883           0 :         if (h->flags & AVIO_FLAG_READ) {
     884             :             /* input */
     885           0 :             if (num_include_sources && num_exclude_sources) {
     886           0 :                 av_log(h, AV_LOG_ERROR, "Simultaneously including and excluding multicast sources is not supported\n");
     887           0 :                 goto fail;
     888             :             }
     889           0 :             if (num_include_sources) {
     890           0 :                 if (udp_set_multicast_sources(h, udp_fd,
     891           0 :                                               (struct sockaddr *)&s->dest_addr,
     892             :                                               s->dest_addr_len,
     893             :                                               include_sources,
     894             :                                               num_include_sources, 1) < 0)
     895           0 :                     goto fail;
     896             :             } else {
     897           0 :                 if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr,(struct sockaddr *)&s->local_addr_storage) < 0)
     898           0 :                     goto fail;
     899             :             }
     900           0 :             if (num_exclude_sources) {
     901           0 :                 if (udp_set_multicast_sources(h, udp_fd,
     902           0 :                                               (struct sockaddr *)&s->dest_addr,
     903             :                                               s->dest_addr_len,
     904             :                                               exclude_sources,
     905             :                                               num_exclude_sources, 0) < 0)
     906           0 :                     goto fail;
     907             :             }
     908             :         }
     909             :     }
     910             : 
     911           0 :     if (is_output) {
     912             :         /* limit the tx buf size to limit latency */
     913           0 :         tmp = s->buffer_size;
     914           0 :         if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) {
     915           0 :             log_net_error(h, AV_LOG_ERROR, "setsockopt(SO_SNDBUF)");
     916           0 :             goto fail;
     917             :         }
     918             :     } else {
     919             :         /* set udp recv buffer size to the requested value (default 64K) */
     920           0 :         tmp = s->buffer_size;
     921           0 :         if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) {
     922           0 :             log_net_error(h, AV_LOG_WARNING, "setsockopt(SO_RECVBUF)");
     923             :         }
     924           0 :         len = sizeof(tmp);
     925           0 :         if (getsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, &len) < 0) {
     926           0 :             log_net_error(h, AV_LOG_WARNING, "getsockopt(SO_RCVBUF)");
     927             :         } else {
     928           0 :             av_log(h, AV_LOG_DEBUG, "end receive buffer size reported is %d\n", tmp);
     929           0 :             if(tmp < s->buffer_size)
     930           0 :                 av_log(h, AV_LOG_WARNING, "attempted to set receive buffer to size %d but it only ended up set as %d", s->buffer_size, tmp);
     931             :         }
     932             : 
     933             :         /* make the socket non-blocking */
     934           0 :         ff_socket_nonblock(udp_fd, 1);
     935             :     }
     936           0 :     if (s->is_connected) {
     937           0 :         if (connect(udp_fd, (struct sockaddr *) &s->dest_addr, s->dest_addr_len)) {
     938           0 :             log_net_error(h, AV_LOG_ERROR, "connect");
     939           0 :             goto fail;
     940             :         }
     941             :     }
     942             : 
     943           0 :     for (i = 0; i < num_include_sources; i++)
     944           0 :         av_freep(&include_sources[i]);
     945           0 :     for (i = 0; i < num_exclude_sources; i++)
     946           0 :         av_freep(&exclude_sources[i]);
     947             : 
     948           0 :     s->udp_fd = udp_fd;
     949             : 
     950             : #if HAVE_PTHREAD_CANCEL
     951             :     /*
     952             :       Create thread in case of:
     953             :       1. Input and circular_buffer_size is set
     954             :       2. Output and bitrate and circular_buffer_size is set
     955             :     */
     956             : 
     957           0 :     if (is_output && s->bitrate && !s->circular_buffer_size) {
     958             :         /* Warn user in case of 'circular_buffer_size' is not set */
     959           0 :         av_log(h, AV_LOG_WARNING,"'bitrate' option was set but 'circular_buffer_size' is not, but required\n");
     960             :     }
     961             : 
     962           0 :     if ((!is_output && s->circular_buffer_size) || (is_output && s->bitrate && s->circular_buffer_size)) {
     963             :         int ret;
     964             : 
     965             :         /* start the task going */
     966           0 :         s->fifo = av_fifo_alloc(s->circular_buffer_size);
     967           0 :         ret = pthread_mutex_init(&s->mutex, NULL);
     968           0 :         if (ret != 0) {
     969           0 :             av_log(h, AV_LOG_ERROR, "pthread_mutex_init failed : %s\n", strerror(ret));
     970           0 :             goto fail;
     971             :         }
     972           0 :         ret = pthread_cond_init(&s->cond, NULL);
     973           0 :         if (ret != 0) {
     974           0 :             av_log(h, AV_LOG_ERROR, "pthread_cond_init failed : %s\n", strerror(ret));
     975           0 :             goto cond_fail;
     976             :         }
     977           0 :         ret = pthread_create(&s->circular_buffer_thread, NULL, is_output?circular_buffer_task_tx:circular_buffer_task_rx, h);
     978           0 :         if (ret != 0) {
     979           0 :             av_log(h, AV_LOG_ERROR, "pthread_create failed : %s\n", strerror(ret));
     980           0 :             goto thread_fail;
     981             :         }
     982           0 :         s->thread_started = 1;
     983             :     }
     984             : #endif
     985             : 
     986           0 :     return 0;
     987             : #if HAVE_PTHREAD_CANCEL
     988           0 :  thread_fail:
     989           0 :     pthread_cond_destroy(&s->cond);
     990           0 :  cond_fail:
     991           0 :     pthread_mutex_destroy(&s->mutex);
     992             : #endif
     993           0 :  fail:
     994           0 :     if (udp_fd >= 0)
     995           0 :         closesocket(udp_fd);
     996           0 :     av_fifo_freep(&s->fifo);
     997           0 :     for (i = 0; i < num_include_sources; i++)
     998           0 :         av_freep(&include_sources[i]);
     999           0 :     for (i = 0; i < num_exclude_sources; i++)
    1000           0 :         av_freep(&exclude_sources[i]);
    1001           0 :     return AVERROR(EIO);
    1002             : }
    1003             : 
    1004           0 : static int udplite_open(URLContext *h, const char *uri, int flags)
    1005             : {
    1006           0 :     UDPContext *s = h->priv_data;
    1007             : 
    1008             :     // set default checksum coverage
    1009           0 :     s->udplite_coverage = UDP_HEADER_SIZE;
    1010             : 
    1011           0 :     return udp_open(h, uri, flags);
    1012             : }
    1013             : 
    1014           0 : static int udp_read(URLContext *h, uint8_t *buf, int size)
    1015             : {
    1016           0 :     UDPContext *s = h->priv_data;
    1017             :     int ret;
    1018             : #if HAVE_PTHREAD_CANCEL
    1019           0 :     int avail, nonblock = h->flags & AVIO_FLAG_NONBLOCK;
    1020             : 
    1021           0 :     if (s->fifo) {
    1022           0 :         pthread_mutex_lock(&s->mutex);
    1023             :         do {
    1024           0 :             avail = av_fifo_size(s->fifo);
    1025           0 :             if (avail) { // >=size) {
    1026             :                 uint8_t tmp[4];
    1027             : 
    1028           0 :                 av_fifo_generic_read(s->fifo, tmp, 4, NULL);
    1029           0 :                 avail= AV_RL32(tmp);
    1030           0 :                 if(avail > size){
    1031           0 :                     av_log(h, AV_LOG_WARNING, "Part of datagram lost due to insufficient buffer size\n");
    1032           0 :                     avail= size;
    1033             :                 }
    1034             : 
    1035           0 :                 av_fifo_generic_read(s->fifo, buf, avail, NULL);
    1036           0 :                 av_fifo_drain(s->fifo, AV_RL32(tmp) - avail);
    1037           0 :                 pthread_mutex_unlock(&s->mutex);
    1038           0 :                 return avail;
    1039           0 :             } else if(s->circular_buffer_error){
    1040           0 :                 int err = s->circular_buffer_error;
    1041           0 :                 pthread_mutex_unlock(&s->mutex);
    1042           0 :                 return err;
    1043           0 :             } else if(nonblock) {
    1044           0 :                 pthread_mutex_unlock(&s->mutex);
    1045           0 :                 return AVERROR(EAGAIN);
    1046             :             }
    1047             :             else {
    1048             :                 /* FIXME: using the monotonic clock would be better,
    1049             :                    but it does not exist on all supported platforms. */
    1050           0 :                 int64_t t = av_gettime() + 100000;
    1051           0 :                 struct timespec tv = { .tv_sec  =  t / 1000000,
    1052           0 :                                        .tv_nsec = (t % 1000000) * 1000 };
    1053           0 :                 if (pthread_cond_timedwait(&s->cond, &s->mutex, &tv) < 0) {
    1054           0 :                     pthread_mutex_unlock(&s->mutex);
    1055           0 :                     return AVERROR(errno == ETIMEDOUT ? EAGAIN : errno);
    1056             :                 }
    1057           0 :                 nonblock = 1;
    1058             :             }
    1059             :         } while( 1);
    1060             :     }
    1061             : #endif
    1062             : 
    1063           0 :     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
    1064           0 :         ret = ff_network_wait_fd(s->udp_fd, 0);
    1065           0 :         if (ret < 0)
    1066           0 :             return ret;
    1067             :     }
    1068           0 :     ret = recv(s->udp_fd, buf, size, 0);
    1069             : 
    1070           0 :     return ret < 0 ? ff_neterrno() : ret;
    1071             : }
    1072             : 
    1073           0 : static int udp_write(URLContext *h, const uint8_t *buf, int size)
    1074             : {
    1075           0 :     UDPContext *s = h->priv_data;
    1076             :     int ret;
    1077             : 
    1078             : #if HAVE_PTHREAD_CANCEL
    1079           0 :     if (s->fifo) {
    1080             :         uint8_t tmp[4];
    1081             : 
    1082           0 :         pthread_mutex_lock(&s->mutex);
    1083             : 
    1084             :         /*
    1085             :           Return error if last tx failed.
    1086             :           Here we can't know on which packet error was, but it needs to know that error exists.
    1087             :         */
    1088           0 :         if (s->circular_buffer_error<0) {
    1089           0 :             int err=s->circular_buffer_error;
    1090           0 :             pthread_mutex_unlock(&s->mutex);
    1091           0 :             return err;
    1092             :         }
    1093             : 
    1094           0 :         if(av_fifo_space(s->fifo) < size + 4) {
    1095             :             /* What about a partial packet tx ? */
    1096           0 :             pthread_mutex_unlock(&s->mutex);
    1097           0 :             return AVERROR(ENOMEM);
    1098             :         }
    1099           0 :         AV_WL32(tmp, size);
    1100           0 :         av_fifo_generic_write(s->fifo, tmp, 4, NULL); /* size of packet */
    1101           0 :         av_fifo_generic_write(s->fifo, (uint8_t *)buf, size, NULL); /* the data */
    1102           0 :         pthread_cond_signal(&s->cond);
    1103           0 :         pthread_mutex_unlock(&s->mutex);
    1104           0 :         return size;
    1105             :     }
    1106             : #endif
    1107           0 :     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
    1108           0 :         ret = ff_network_wait_fd(s->udp_fd, 1);
    1109           0 :         if (ret < 0)
    1110           0 :             return ret;
    1111             :     }
    1112             : 
    1113           0 :     if (!s->is_connected) {
    1114           0 :         ret = sendto (s->udp_fd, buf, size, 0,
    1115           0 :                       (struct sockaddr *) &s->dest_addr,
    1116           0 :                       s->dest_addr_len);
    1117             :     } else
    1118           0 :         ret = send(s->udp_fd, buf, size, 0);
    1119             : 
    1120           0 :     return ret < 0 ? ff_neterrno() : ret;
    1121             : }
    1122             : 
    1123           0 : static int udp_close(URLContext *h)
    1124             : {
    1125           0 :     UDPContext *s = h->priv_data;
    1126             : 
    1127             : #if HAVE_PTHREAD_CANCEL
    1128             :     // Request close once writing is finished
    1129           0 :     if (s->thread_started && !(h->flags & AVIO_FLAG_READ)) {
    1130           0 :         pthread_mutex_lock(&s->mutex);
    1131           0 :         s->close_req = 1;
    1132           0 :         pthread_cond_signal(&s->cond);
    1133           0 :         pthread_mutex_unlock(&s->mutex);
    1134             :     }
    1135             : #endif
    1136             : 
    1137           0 :     if (s->is_multicast && (h->flags & AVIO_FLAG_READ))
    1138           0 :         udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr,(struct sockaddr *)&s->local_addr_storage);
    1139             : #if HAVE_PTHREAD_CANCEL
    1140           0 :     if (s->thread_started) {
    1141             :         int ret;
    1142             :         // Cancel only read, as write has been signaled as success to the user
    1143           0 :         if (h->flags & AVIO_FLAG_READ)
    1144           0 :             pthread_cancel(s->circular_buffer_thread);
    1145           0 :         ret = pthread_join(s->circular_buffer_thread, NULL);
    1146           0 :         if (ret != 0)
    1147           0 :             av_log(h, AV_LOG_ERROR, "pthread_join(): %s\n", strerror(ret));
    1148           0 :         pthread_mutex_destroy(&s->mutex);
    1149           0 :         pthread_cond_destroy(&s->cond);
    1150             :     }
    1151             : #endif
    1152           0 :     closesocket(s->udp_fd);
    1153           0 :     av_fifo_freep(&s->fifo);
    1154           0 :     return 0;
    1155             : }
    1156             : 
    1157             : const URLProtocol ff_udp_protocol = {
    1158             :     .name                = "udp",
    1159             :     .url_open            = udp_open,
    1160             :     .url_read            = udp_read,
    1161             :     .url_write           = udp_write,
    1162             :     .url_close           = udp_close,
    1163             :     .url_get_file_handle = udp_get_file_handle,
    1164             :     .priv_data_size      = sizeof(UDPContext),
    1165             :     .priv_data_class     = &udp_class,
    1166             :     .flags               = URL_PROTOCOL_FLAG_NETWORK,
    1167             : };
    1168             : 
    1169             : const URLProtocol ff_udplite_protocol = {
    1170             :     .name                = "udplite",
    1171             :     .url_open            = udplite_open,
    1172             :     .url_read            = udp_read,
    1173             :     .url_write           = udp_write,
    1174             :     .url_close           = udp_close,
    1175             :     .url_get_file_handle = udp_get_file_handle,
    1176             :     .priv_data_size      = sizeof(UDPContext),
    1177             :     .priv_data_class     = &udplite_context_class,
    1178             :     .flags               = URL_PROTOCOL_FLAG_NETWORK,
    1179             : };

Generated by: LCOV version 1.13