Mercurial > libavformat.hg
annotate udp.c @ 5266:73615b247438 libavformat
Only read ID3v1 tag if ID3v2 isn't present or is empty.
This prevents the demuxer from exporting multiple semantically identical but
differently named tags.
Patch by Anton Khirnov, wyskas gmail
author | cehoyos |
---|---|
date | Mon, 05 Oct 2009 21:36:56 +0000 |
parents | b34d9614b887 |
children | 9934ca658946 |
rev | line source |
---|---|
0 | 1 /* |
2 * UDP prototype streaming system | |
4251
77e0c7511d41
cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents:
4206
diff
changeset
|
3 * Copyright (c) 2000, 2001, 2002 Fabrice Bellard |
0 | 4 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
5 * This file is part of FFmpeg. |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
6 * |
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
7 * FFmpeg is free software; you can redistribute it and/or |
0 | 8 * modify it under the terms of the GNU Lesser General Public |
9 * License as published by the Free Software Foundation; either | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
10 * version 2.1 of the License, or (at your option) any later version. |
0 | 11 * |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
12 * FFmpeg is distributed in the hope that it will be useful, |
0 | 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 | |
1358
0899bfe4105c
Change license headers to say 'FFmpeg' instead of 'this program/this library'
diego
parents:
1332
diff
changeset
|
18 * License along with FFmpeg; if not, write to the Free Software |
896
edbe5c3717f9
Update licensing information: The FSF changed postal address.
diego
parents:
885
diff
changeset
|
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
0 | 20 */ |
3231 | 21 |
22 /** | |
4331
49c1d3b27727
Use full internal pathname in doxygen @file directives.
diego
parents:
4251
diff
changeset
|
23 * @file libavformat/udp.c |
3231 | 24 * UDP protocol |
25 */ | |
26 | |
3776 | 27 #define _BSD_SOURCE /* Needed for using struct ip_mreq with recent glibc */ |
0 | 28 #include "avformat.h" |
29 #include <unistd.h> | |
1754 | 30 #include "network.h" |
2773 | 31 #include "os_support.h" |
4206 | 32 #if HAVE_SYS_SELECT_H |
4024 | 33 #include <sys/select.h> |
34 #endif | |
4083
2de14ee7b25f
Add sys/time.h header #include, fixes compilation on OS/2.
diego
parents:
4070
diff
changeset
|
35 #include <sys/time.h> |
0 | 36 |
834 | 37 #ifndef IPV6_ADD_MEMBERSHIP |
38 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP | |
39 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP | |
40 #endif | |
3221 | 41 #ifndef IN_MULTICAST |
42 #define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) | |
43 #endif | |
44 #ifndef IN6_IS_ADDR_MULTICAST | |
45 #define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff) | |
46 #endif | |
834 | 47 |
0 | 48 typedef struct { |
49 int udp_fd; | |
50 int ttl; | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
51 int buffer_size; |
0 | 52 int is_multicast; |
53 int local_port; | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
54 int reuse_socket; |
4206 | 55 #if !CONFIG_IPV6 |
0 | 56 struct sockaddr_in dest_addr; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
57 #else |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
58 struct sockaddr_storage dest_addr; |
2738
1f5c5c223764
Remove some ifdefs by using the "dest_addr_len" field in both the IPv4-only
lucabe
parents:
2689
diff
changeset
|
59 #endif |
3287
8570df039c75
Fix type of dest_addr_len to respect return value of udp_set_url.
cehoyos
parents:
3231
diff
changeset
|
60 int dest_addr_len; |
0 | 61 } UDPContext; |
62 | |
63 #define UDP_TX_BUF_SIZE 32768 | |
2391 | 64 #define UDP_MAX_PKT_SIZE 65536 |
0 | 65 |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
66 static int udp_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
67 #ifdef IP_MULTICAST_TTL |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
68 if (addr->sa_family == AF_INET) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
69 if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { |
2768 | 70 av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_MULTICAST_TTL): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
71 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
72 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
73 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
74 #endif |
4206 | 75 #if CONFIG_IPV6 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
76 if (addr->sa_family == AF_INET6) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
77 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { |
2768 | 78 av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_MULTICAST_HOPS): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
79 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
80 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
81 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
82 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
83 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
84 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
85 |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
86 static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
87 #ifdef IP_ADD_MEMBERSHIP |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
88 if (addr->sa_family == AF_INET) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
89 struct ip_mreq mreq; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
90 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
91 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
92 mreq.imr_interface.s_addr= INADDR_ANY; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
93 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
2768 | 94 av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
95 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
96 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
97 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
98 #endif |
4206 | 99 #if CONFIG_IPV6 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
100 if (addr->sa_family == AF_INET6) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
101 struct ipv6_mreq mreq6; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
102 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
103 memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
104 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
105 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
2768 | 106 av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_ADD_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
107 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
108 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
109 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
110 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
111 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
112 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
113 |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
114 static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
115 #ifdef IP_DROP_MEMBERSHIP |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
116 if (addr->sa_family == AF_INET) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
117 struct ip_mreq mreq; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
118 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
119 mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
120 mreq.imr_interface.s_addr= INADDR_ANY; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
121 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
2768 | 122 av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
123 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
124 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
125 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
126 #endif |
4206 | 127 #if CONFIG_IPV6 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
128 if (addr->sa_family == AF_INET6) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
129 struct ipv6_mreq mreq6; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
130 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
131 memcpy(&mreq6.ipv6mr_multiaddr, &(((struct sockaddr_in6 *)addr)->sin6_addr), sizeof(struct in6_addr)); |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
132 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
133 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
2768 | 134 av_log(NULL, AV_LOG_ERROR, "setsockopt(IPV6_DROP_MEMBERSHIP): %s\n", strerror(errno)); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
135 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
136 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
137 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
138 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
139 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
140 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
141 |
4206 | 142 #if CONFIG_IPV6 |
1124
d3aff2c607f9
Add const to (mostly) char* and make some functions static, which aren't used
diego
parents:
896
diff
changeset
|
143 static struct addrinfo* udp_ipv6_resolve_host(const char *hostname, int port, int type, int family, int flags) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
144 struct addrinfo hints, *res = 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
145 int error; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
146 char sport[16]; |
2687
f4d24b10d33d
Resolve hosts and bind sockets even when the local_port is not set (0)
lucabe
parents:
2391
diff
changeset
|
147 const char *node = 0, *service = "0"; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
148 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
149 if (port > 0) { |
644 | 150 snprintf(sport, sizeof(sport), "%d", port); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
151 service = sport; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
152 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
153 if ((hostname) && (hostname[0] != '\0') && (hostname[0] != '?')) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
154 node = hostname; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
155 } |
2688 | 156 memset(&hints, 0, sizeof(hints)); |
157 hints.ai_socktype = type; | |
158 hints.ai_family = family; | |
159 hints.ai_flags = flags; | |
160 if ((error = getaddrinfo(node, service, &hints, &res))) { | |
161 av_log(NULL, AV_LOG_ERROR, "udp_ipv6_resolve_host: %s\n", gai_strerror(error)); | |
162 } | |
163 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
164 return res; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
165 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
166 |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
167 static int udp_set_url(struct sockaddr_storage *addr, const char *hostname, int port) { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
168 struct addrinfo *res0; |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
169 int addr_len; |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
170 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
171 res0 = udp_ipv6_resolve_host(hostname, port, SOCK_DGRAM, AF_UNSPEC, 0); |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
172 if (res0 == 0) return AVERROR(EIO); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
173 memcpy(addr, res0->ai_addr, res0->ai_addrlen); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
174 addr_len = res0->ai_addrlen; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
175 freeaddrinfo(res0); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
176 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
177 return addr_len; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
178 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
179 |
3221 | 180 static int is_multicast_address(struct sockaddr_storage *addr) |
181 { | |
182 if (addr->ss_family == AF_INET) { | |
183 return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); | |
184 } | |
185 if (addr->ss_family == AF_INET6) { | |
186 return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); | |
187 } | |
188 | |
189 return 0; | |
190 } | |
191 | |
2752 | 192 static int udp_socket_create(UDPContext *s, struct sockaddr_storage *addr, int *addr_len) |
193 { | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
194 int udp_fd = -1; |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
195 struct addrinfo *res0 = NULL, *res = NULL; |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
196 int family = AF_UNSPEC; |
885 | 197 |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
198 if (((struct sockaddr *) &s->dest_addr)->sa_family) |
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
199 family = ((struct sockaddr *) &s->dest_addr)->sa_family; |
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
200 res0 = udp_ipv6_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); |
2688 | 201 if (res0 == 0) |
202 goto fail; | |
203 for (res = res0; res; res=res->ai_next) { | |
204 udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); | |
205 if (udp_fd > 0) break; | |
2768 | 206 av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno)); |
2688 | 207 } |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
208 |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
209 if (udp_fd < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
210 goto fail; |
885 | 211 |
2752 | 212 memcpy(addr, res->ai_addr, res->ai_addrlen); |
213 *addr_len = res->ai_addrlen; | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
214 |
2752 | 215 freeaddrinfo(res0); |
885 | 216 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
217 return udp_fd; |
885 | 218 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
219 fail: |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
220 if (udp_fd >= 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
221 closesocket(udp_fd); |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
222 if(res0) |
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
223 freeaddrinfo(res0); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
224 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
225 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
226 |
2752 | 227 static int udp_port(struct sockaddr_storage *addr, int addr_len) |
228 { | |
3025
41d68d056417
Do not use GNU-specific (or BSD-specific or whatever they may be)
rfelker
parents:
2773
diff
changeset
|
229 char sbuf[sizeof(int)*3+1]; |
2752 | 230 |
3025
41d68d056417
Do not use GNU-specific (or BSD-specific or whatever they may be)
rfelker
parents:
2773
diff
changeset
|
231 if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) { |
2768 | 232 av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno)); |
2752 | 233 return -1; |
234 } | |
235 | |
236 return strtol(sbuf, NULL, 10); | |
237 } | |
238 | |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
239 #else |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
240 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
241 static int udp_set_url(struct sockaddr_in *addr, const char *hostname, int port) |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
242 { |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
243 /* set the destination address */ |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
244 if (resolve_host(&addr->sin_addr, hostname) < 0) |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
245 return AVERROR(EIO); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
246 addr->sin_family = AF_INET; |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
247 addr->sin_port = htons(port); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
248 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
249 return sizeof(struct sockaddr_in); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
250 } |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
251 |
3221 | 252 static int is_multicast_address(struct sockaddr_in *addr) |
253 { | |
254 return IN_MULTICAST(ntohl(addr->sin_addr.s_addr)); | |
255 } | |
256 | |
2752 | 257 static int udp_socket_create(UDPContext *s, struct sockaddr_in *addr, int *addr_len) |
258 { | |
259 int fd; | |
260 | |
261 fd = socket(AF_INET, SOCK_DGRAM, 0); | |
262 if (fd < 0) | |
263 return -1; | |
264 | |
265 addr->sin_family = AF_INET; | |
266 addr->sin_addr.s_addr = htonl (INADDR_ANY); | |
267 addr->sin_port = htons(s->local_port); | |
268 *addr_len = sizeof(struct sockaddr_in); | |
269 | |
270 return fd; | |
271 } | |
272 | |
273 static int udp_port(struct sockaddr_in *addr, int len) | |
274 { | |
275 return ntohs(addr->sin_port); | |
276 } | |
2162 | 277 #endif /* CONFIG_IPV6 */ |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
278 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
279 |
0 | 280 /** |
281 * If no filename is given to av_open_input_file because you want to | |
282 * get the local port first, then you must call this function to set | |
283 * the remote server address. | |
284 * | |
285 * url syntax: udp://host:port[?option=val...] | |
3221 | 286 * option: 'ttl=n' : set the ttl value (for multicast only) |
0 | 287 * 'localport=n' : set the local port |
62 | 288 * 'pkt_size=n' : set max packet size |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
289 * 'reuse=1' : enable reusing the socket |
0 | 290 * |
291 * @param s1 media file context | |
292 * @param uri of the remote server | |
293 * @return zero if no error. | |
294 */ | |
295 int udp_set_remote_url(URLContext *h, const char *uri) | |
296 { | |
297 UDPContext *s = h->priv_data; | |
298 char hostname[256]; | |
299 int port; | |
885 | 300 |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
301 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
0 | 302 |
303 /* set the destination address */ | |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
304 s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
305 if (s->dest_addr_len < 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
306 return AVERROR(EIO); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
307 } |
3221 | 308 s->is_multicast = is_multicast_address(&s->dest_addr); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
309 |
0 | 310 return 0; |
311 } | |
312 | |
313 /** | |
314 * Return the local port used by the UDP connexion | |
315 * @param s1 media file context | |
316 * @return the local port number | |
317 */ | |
318 int udp_get_local_port(URLContext *h) | |
319 { | |
320 UDPContext *s = h->priv_data; | |
321 return s->local_port; | |
322 } | |
323 | |
324 /** | |
325 * Return the udp file handle for select() usage to wait for several RTP | |
326 * streams at the same time. | |
327 * @param h media file context | |
328 */ | |
4640
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
329 #if (LIBAVFORMAT_VERSION_MAJOR >= 53) |
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
330 static |
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
331 #endif |
0 | 332 int udp_get_file_handle(URLContext *h) |
333 { | |
334 UDPContext *s = h->priv_data; | |
335 return s->udp_fd; | |
336 } | |
337 | |
338 /* put it in UDP context */ | |
339 /* return non zero if error */ | |
340 static int udp_open(URLContext *h, const char *uri, int flags) | |
341 { | |
342 char hostname[1024]; | |
4070 | 343 int port, udp_fd = -1, tmp, bind_ret = -1; |
0 | 344 UDPContext *s = NULL; |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
345 int is_output; |
0 | 346 const char *p; |
347 char buf[256]; | |
4206 | 348 #if !CONFIG_IPV6 |
2751 | 349 struct sockaddr_in my_addr; |
2752 | 350 #else |
351 struct sockaddr_storage my_addr; | |
352 #endif | |
683
095009fc2f35
kill warnings patch by (M«©ns Rullg«©rd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
353 int len; |
0 | 354 |
355 h->is_streamed = 1; | |
62 | 356 h->max_packet_size = 1472; |
0 | 357 |
358 is_output = (flags & URL_WRONLY); | |
885 | 359 |
3753
42ed3629601d
Fix memleak on some OSes in case network initialization fails. See
rbultje
parents:
3287
diff
changeset
|
360 if(!ff_network_init()) |
42ed3629601d
Fix memleak on some OSes in case network initialization fails. See
rbultje
parents:
3287
diff
changeset
|
361 return AVERROR(EIO); |
42ed3629601d
Fix memleak on some OSes in case network initialization fails. See
rbultje
parents:
3287
diff
changeset
|
362 |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
363 s = av_mallocz(sizeof(UDPContext)); |
0 | 364 if (!s) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
365 return AVERROR(ENOMEM); |
0 | 366 |
367 h->priv_data = s; | |
368 s->ttl = 16; | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
369 s->buffer_size = is_output ? UDP_TX_BUF_SIZE : UDP_MAX_PKT_SIZE; |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
370 |
0 | 371 p = strchr(uri, '?'); |
372 if (p) { | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
373 s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p); |
0 | 374 if (find_info_tag(buf, sizeof(buf), "ttl", p)) { |
375 s->ttl = strtol(buf, NULL, 10); | |
376 } | |
377 if (find_info_tag(buf, sizeof(buf), "localport", p)) { | |
378 s->local_port = strtol(buf, NULL, 10); | |
379 } | |
62 | 380 if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { |
381 h->max_packet_size = strtol(buf, NULL, 10); | |
382 } | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
383 if (find_info_tag(buf, sizeof(buf), "buffer_size", p)) { |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
384 s->buffer_size = strtol(buf, NULL, 10); |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
385 } |
0 | 386 } |
387 | |
388 /* fill the dest addr */ | |
511
056991ab9f10
HTTP Authentication Patch by (Petr Doubek <doubek at vision dot ee dot ethz dot ch>)
michael
parents:
482
diff
changeset
|
389 url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
885 | 390 |
0 | 391 /* XXX: fix url_split */ |
392 if (hostname[0] == '\0' || hostname[0] == '?') { | |
393 /* only accepts null hostname if input */ | |
3221 | 394 if (flags & URL_WRONLY) |
0 | 395 goto fail; |
396 } else { | |
397 udp_set_remote_url(h, uri); | |
398 } | |
399 | |
2750
b3a11a0966af
Use the same code to set local_port in the IPv4-only case and in the
lucabe
parents:
2744
diff
changeset
|
400 if (s->is_multicast && !(h->flags & URL_WRONLY)) |
b3a11a0966af
Use the same code to set local_port in the IPv4-only case and in the
lucabe
parents:
2744
diff
changeset
|
401 s->local_port = port; |
2752 | 402 udp_fd = udp_socket_create(s, &my_addr, &len); |
0 | 403 if (udp_fd < 0) |
404 goto fail; | |
405 | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
406 if (s->reuse_socket) |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
407 if (setsockopt (udp_fd, SOL_SOCKET, SO_REUSEADDR, &(s->reuse_socket), sizeof(s->reuse_socket)) != 0) |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
408 goto fail; |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
409 |
0 | 410 /* the bind is needed to give a port to the socket now */ |
4070 | 411 /* if multicast, try the multicast address bind first */ |
412 if (s->is_multicast && !(h->flags & URL_WRONLY)) { | |
413 bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); | |
414 } | |
415 /* bind to the local address if not multicast or if the multicast | |
416 * bind failed */ | |
417 if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) | |
0 | 418 goto fail; |
419 | |
2751 | 420 len = sizeof(my_addr); |
421 getsockname(udp_fd, (struct sockaddr *)&my_addr, &len); | |
2752 | 422 s->local_port = udp_port(&my_addr, len); |
423 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
424 if (s->is_multicast) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
425 if (h->flags & URL_WRONLY) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
426 /* output */ |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
427 if (udp_set_multicast_ttl(udp_fd, s->ttl, (struct sockaddr *)&s->dest_addr) < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
428 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
429 } else { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
430 /* input */ |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
431 if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
432 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
433 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
434 } |
0 | 435 |
436 if (is_output) { | |
437 /* limit the tx buf size to limit latency */ | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
438 tmp = s->buffer_size; |
0 | 439 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { |
2768 | 440 av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno)); |
0 | 441 goto fail; |
442 } | |
2391 | 443 } else { |
444 /* set udp recv buffer size to the largest possible udp packet size to | |
445 * avoid losing data on OSes that set this too low by default. */ | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
446 tmp = s->buffer_size; |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
447 if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &tmp, sizeof(tmp)) < 0) { |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
448 av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_RECVBUF): %s\n", strerror(errno)); |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
449 } |
4035
8c161751e4c7
Get rid of MSG_DONTWAIT using a more standard way to use a socket
benoit
parents:
4024
diff
changeset
|
450 /* make the socket non-blocking */ |
8c161751e4c7
Get rid of MSG_DONTWAIT using a more standard way to use a socket
benoit
parents:
4024
diff
changeset
|
451 ff_socket_nonblock(udp_fd, 1); |
0 | 452 } |
453 | |
454 s->udp_fd = udp_fd; | |
455 return 0; | |
456 fail: | |
457 if (udp_fd >= 0) | |
458 closesocket(udp_fd); | |
459 av_free(s); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
460 return AVERROR(EIO); |
0 | 461 } |
462 | |
65 | 463 static int udp_read(URLContext *h, uint8_t *buf, int size) |
0 | 464 { |
465 UDPContext *s = h->priv_data; | |
1332 | 466 int len; |
4024 | 467 fd_set rfds; |
468 int ret; | |
469 struct timeval tv; | |
0 | 470 |
471 for(;;) { | |
4024 | 472 if (url_interrupt_cb()) |
473 return AVERROR(EINTR); | |
474 FD_ZERO(&rfds); | |
475 FD_SET(s->udp_fd, &rfds); | |
476 tv.tv_sec = 0; | |
477 tv.tv_usec = 100 * 1000; | |
478 ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv); | |
479 if (ret < 0) | |
480 return AVERROR(EIO); | |
481 if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) | |
482 continue; | |
4035
8c161751e4c7
Get rid of MSG_DONTWAIT using a more standard way to use a socket
benoit
parents:
4024
diff
changeset
|
483 len = recv(s->udp_fd, buf, size, 0); |
0 | 484 if (len < 0) { |
2056
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
485 if (ff_neterrno() != FF_NETERROR(EAGAIN) && |
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
486 ff_neterrno() != FF_NETERROR(EINTR)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
487 return AVERROR(EIO); |
0 | 488 } else { |
489 break; | |
490 } | |
491 } | |
492 return len; | |
493 } | |
494 | |
65 | 495 static int udp_write(URLContext *h, uint8_t *buf, int size) |
0 | 496 { |
497 UDPContext *s = h->priv_data; | |
498 int ret; | |
499 | |
500 for(;;) { | |
885 | 501 ret = sendto (s->udp_fd, buf, size, 0, |
0 | 502 (struct sockaddr *) &s->dest_addr, |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
503 s->dest_addr_len); |
0 | 504 if (ret < 0) { |
2056
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
505 if (ff_neterrno() != FF_NETERROR(EINTR) && |
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
506 ff_neterrno() != FF_NETERROR(EAGAIN)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
507 return AVERROR(EIO); |
0 | 508 } else { |
509 break; | |
510 } | |
511 } | |
512 return size; | |
513 } | |
514 | |
515 static int udp_close(URLContext *h) | |
516 { | |
517 UDPContext *s = h->priv_data; | |
518 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
519 if (s->is_multicast && !(h->flags & URL_WRONLY)) |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
520 udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); |
0 | 521 closesocket(s->udp_fd); |
2351
b9a881c0967e
Add initialization and cleanup functions for Winsock
ramiro
parents:
2274
diff
changeset
|
522 ff_network_close(); |
0 | 523 av_free(s); |
524 return 0; | |
525 } | |
526 | |
527 URLProtocol udp_protocol = { | |
528 "udp", | |
529 udp_open, | |
530 udp_read, | |
531 udp_write, | |
532 NULL, /* seek */ | |
533 udp_close, | |
4640
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
534 .url_get_file_handle = udp_get_file_handle, |
0 | 535 }; |