Mercurial > libavformat.hg
annotate udp.c @ 6048:e507a21a9566 libavformat
matroskaenc: Write codec time base as default duration for video tracks.
This isn't exactly semantically equivalent, but the field has already been
long abused to mean this, and writing it helps in determining a decent cfr
time base when transcoding from a mkv where the video codec stores none (VP8).
author | conrad |
---|---|
date | Mon, 24 May 2010 08:58:19 +0000 |
parents | 178de7695c6c |
children | 7fdda2416684 |
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 /** | |
5969
178de7695c6c
Remove explicit filename from Doxygen @file commands.
diego
parents:
5896
diff
changeset
|
23 * @file |
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> | |
5837
d605f589f0be
move ff_url_split() and ff_url_join() declarations to internal.h
aurel
parents:
5775
diff
changeset
|
30 #include "internal.h" |
1754 | 31 #include "network.h" |
2773 | 32 #include "os_support.h" |
4206 | 33 #if HAVE_SYS_SELECT_H |
4024 | 34 #include <sys/select.h> |
35 #endif | |
4083
2de14ee7b25f
Add sys/time.h header #include, fixes compilation on OS/2.
diego
parents:
4070
diff
changeset
|
36 #include <sys/time.h> |
0 | 37 |
834 | 38 #ifndef IPV6_ADD_MEMBERSHIP |
39 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP | |
40 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP | |
41 #endif | |
3221 | 42 #ifndef IN_MULTICAST |
43 #define IN_MULTICAST(a) ((((uint32_t)(a)) & 0xf0000000) == 0xe0000000) | |
44 #endif | |
45 #ifndef IN6_IS_ADDR_MULTICAST | |
46 #define IN6_IS_ADDR_MULTICAST(a) (((uint8_t *) (a))[0] == 0xff) | |
47 #endif | |
834 | 48 |
0 | 49 typedef struct { |
50 int udp_fd; | |
51 int ttl; | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
52 int buffer_size; |
0 | 53 int is_multicast; |
54 int local_port; | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
55 int reuse_socket; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
56 struct sockaddr_storage dest_addr; |
3287
8570df039c75
Fix type of dest_addr_len to respect return value of udp_set_url.
cehoyos
parents:
3231
diff
changeset
|
57 int dest_addr_len; |
0 | 58 } UDPContext; |
59 | |
60 #define UDP_TX_BUF_SIZE 32768 | |
2391 | 61 #define UDP_MAX_PKT_SIZE 65536 |
0 | 62 |
5576 | 63 static int udp_set_multicast_ttl(int sockfd, int mcastTTL, |
64 struct sockaddr *addr) | |
65 { | |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
66 #ifdef IP_MULTICAST_TTL |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
67 if (addr->sa_family == AF_INET) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
68 if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL, sizeof(mcastTTL)) < 0) { |
2768 | 69 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
|
70 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
71 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
72 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
73 #endif |
5567
9934ca658946
Remove IPv4-only codepath. Patch by Martin Storsj <$first $first st>.
rbultje
parents:
4640
diff
changeset
|
74 #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
75 if (addr->sa_family == AF_INET6) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
76 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL, sizeof(mcastTTL)) < 0) { |
2768 | 77 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
|
78 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
79 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
80 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
81 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
82 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
83 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
84 |
5576 | 85 static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) |
86 { | |
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 |
5567
9934ca658946
Remove IPv4-only codepath. Patch by Martin Storsj <$first $first st>.
rbultje
parents:
4640
diff
changeset
|
99 #if HAVE_STRUCT_IPV6_MREQ |
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 |
5576 | 114 static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) |
115 { | |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
116 #ifdef IP_DROP_MEMBERSHIP |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
117 if (addr->sa_family == AF_INET) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
118 struct ip_mreq mreq; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
119 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
120 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
|
121 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
|
122 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
2768 | 123 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
|
124 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
125 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
126 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
127 #endif |
5567
9934ca658946
Remove IPv4-only codepath. Patch by Martin Storsj <$first $first st>.
rbultje
parents:
4640
diff
changeset
|
128 #if HAVE_STRUCT_IPV6_MREQ |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
129 if (addr->sa_family == AF_INET6) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
130 struct ipv6_mreq mreq6; |
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
131 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
132 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
|
133 mreq6.ipv6mr_interface= 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
134 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, &mreq6, sizeof(mreq6)) < 0) { |
2768 | 135 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
|
136 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
137 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
138 } |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
139 #endif |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
140 return 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
141 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
142 |
5576 | 143 static struct addrinfo* udp_resolve_host(const char *hostname, int port, |
144 int type, int family, int flags) | |
145 { | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
146 struct addrinfo hints, *res = 0; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
147 int error; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
148 char sport[16]; |
2687
f4d24b10d33d
Resolve hosts and bind sockets even when the local_port is not set (0)
lucabe
parents:
2391
diff
changeset
|
149 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
|
150 |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
151 if (port > 0) { |
644 | 152 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
|
153 service = sport; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
154 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
155 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
|
156 node = hostname; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
157 } |
2688 | 158 memset(&hints, 0, sizeof(hints)); |
159 hints.ai_socktype = type; | |
160 hints.ai_family = family; | |
161 hints.ai_flags = flags; | |
162 if ((error = getaddrinfo(node, service, &hints, &res))) { | |
5731
c5a662ed3ab5
Explicitly set struct addrinfo to NULL if getaddrinfo failed instead of
reimar
parents:
5576
diff
changeset
|
163 res = NULL; |
5575
d40a7e8259ff
Rename a function which is no longer ipv6-specific. Patch by Martin Storsj
rbultje
parents:
5567
diff
changeset
|
164 av_log(NULL, AV_LOG_ERROR, "udp_resolve_host: %s\n", gai_strerror(error)); |
2688 | 165 } |
166 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
167 return res; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
168 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
169 |
5576 | 170 static int udp_set_url(struct sockaddr_storage *addr, |
171 const char *hostname, int port) | |
172 { | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
173 struct addrinfo *res0; |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
174 int addr_len; |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
175 |
5575
d40a7e8259ff
Rename a function which is no longer ipv6-specific. Patch by Martin Storsj
rbultje
parents:
5567
diff
changeset
|
176 res0 = udp_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
|
177 if (res0 == 0) return AVERROR(EIO); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
178 memcpy(addr, res0->ai_addr, res0->ai_addrlen); |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
179 addr_len = res0->ai_addrlen; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
180 freeaddrinfo(res0); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
181 |
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
182 return addr_len; |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
183 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
184 |
3221 | 185 static int is_multicast_address(struct sockaddr_storage *addr) |
186 { | |
187 if (addr->ss_family == AF_INET) { | |
188 return IN_MULTICAST(ntohl(((struct sockaddr_in *)addr)->sin_addr.s_addr)); | |
189 } | |
5567
9934ca658946
Remove IPv4-only codepath. Patch by Martin Storsj <$first $first st>.
rbultje
parents:
4640
diff
changeset
|
190 #if HAVE_STRUCT_SOCKADDR_IN6 |
3221 | 191 if (addr->ss_family == AF_INET6) { |
192 return IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6 *)addr)->sin6_addr); | |
193 } | |
5567
9934ca658946
Remove IPv4-only codepath. Patch by Martin Storsj <$first $first st>.
rbultje
parents:
4640
diff
changeset
|
194 #endif |
3221 | 195 |
196 return 0; | |
197 } | |
198 | |
5576 | 199 static int udp_socket_create(UDPContext *s, |
200 struct sockaddr_storage *addr, int *addr_len) | |
2752 | 201 { |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
202 int udp_fd = -1; |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
203 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
|
204 int family = AF_UNSPEC; |
885 | 205 |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
206 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
|
207 family = ((struct sockaddr *) &s->dest_addr)->sa_family; |
5575
d40a7e8259ff
Rename a function which is no longer ipv6-specific. Patch by Martin Storsj
rbultje
parents:
5567
diff
changeset
|
208 res0 = udp_resolve_host(0, s->local_port, SOCK_DGRAM, family, AI_PASSIVE); |
2688 | 209 if (res0 == 0) |
210 goto fail; | |
211 for (res = res0; res; res=res->ai_next) { | |
212 udp_fd = socket(res->ai_family, SOCK_DGRAM, 0); | |
213 if (udp_fd > 0) break; | |
2768 | 214 av_log(NULL, AV_LOG_ERROR, "socket: %s\n", strerror(errno)); |
2688 | 215 } |
825
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
216 |
c8d4a65729c5
udp ipv6 localhost resolving patch by ("Hans Zandbelt": Hans Zandbelt, telin nl)
michael
parents:
815
diff
changeset
|
217 if (udp_fd < 0) |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
218 goto fail; |
885 | 219 |
2752 | 220 memcpy(addr, res->ai_addr, res->ai_addrlen); |
221 *addr_len = res->ai_addrlen; | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
222 |
2752 | 223 freeaddrinfo(res0); |
885 | 224 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
225 return udp_fd; |
885 | 226 |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
227 fail: |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
228 if (udp_fd >= 0) |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
229 closesocket(udp_fd); |
683
095009fc2f35
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
230 if(res0) |
095009fc2f35
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
231 freeaddrinfo(res0); |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
232 return -1; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
233 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
234 |
2752 | 235 static int udp_port(struct sockaddr_storage *addr, int addr_len) |
236 { | |
3025
41d68d056417
Do not use GNU-specific (or BSD-specific or whatever they may be)
rfelker
parents:
2773
diff
changeset
|
237 char sbuf[sizeof(int)*3+1]; |
2752 | 238 |
3025
41d68d056417
Do not use GNU-specific (or BSD-specific or whatever they may be)
rfelker
parents:
2773
diff
changeset
|
239 if (getnameinfo((struct sockaddr *)addr, addr_len, NULL, 0, sbuf, sizeof(sbuf), NI_NUMERICSERV) != 0) { |
2768 | 240 av_log(NULL, AV_LOG_ERROR, "getnameinfo: %s\n", strerror(errno)); |
2752 | 241 return -1; |
242 } | |
243 | |
244 return strtol(sbuf, NULL, 10); | |
245 } | |
246 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
247 |
0 | 248 /** |
249 * If no filename is given to av_open_input_file because you want to | |
250 * get the local port first, then you must call this function to set | |
251 * the remote server address. | |
252 * | |
253 * url syntax: udp://host:port[?option=val...] | |
3221 | 254 * option: 'ttl=n' : set the ttl value (for multicast only) |
0 | 255 * 'localport=n' : set the local port |
62 | 256 * '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
|
257 * 'reuse=1' : enable reusing the socket |
0 | 258 * |
259 * @param s1 media file context | |
260 * @param uri of the remote server | |
261 * @return zero if no error. | |
262 */ | |
263 int udp_set_remote_url(URLContext *h, const char *uri) | |
264 { | |
265 UDPContext *s = h->priv_data; | |
266 char hostname[256]; | |
267 int port; | |
885 | 268 |
5775 | 269 ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
0 | 270 |
271 /* set the destination address */ | |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
272 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
|
273 if (s->dest_addr_len < 0) { |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
274 return AVERROR(EIO); |
2743
a847a9eda9b2
Simplify set_remote_url(), and remove some code duplication
lucabe
parents:
2742
diff
changeset
|
275 } |
3221 | 276 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
|
277 |
0 | 278 return 0; |
279 } | |
280 | |
281 /** | |
282 * Return the local port used by the UDP connexion | |
283 * @param s1 media file context | |
284 * @return the local port number | |
285 */ | |
286 int udp_get_local_port(URLContext *h) | |
287 { | |
288 UDPContext *s = h->priv_data; | |
289 return s->local_port; | |
290 } | |
291 | |
292 /** | |
293 * Return the udp file handle for select() usage to wait for several RTP | |
294 * streams at the same time. | |
295 * @param h media file context | |
296 */ | |
4640
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
297 #if (LIBAVFORMAT_VERSION_MAJOR >= 53) |
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
298 static |
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
299 #endif |
0 | 300 int udp_get_file_handle(URLContext *h) |
301 { | |
302 UDPContext *s = h->priv_data; | |
303 return s->udp_fd; | |
304 } | |
305 | |
306 /* put it in UDP context */ | |
307 /* return non zero if error */ | |
308 static int udp_open(URLContext *h, const char *uri, int flags) | |
309 { | |
310 char hostname[1024]; | |
4070 | 311 int port, udp_fd = -1, tmp, bind_ret = -1; |
0 | 312 UDPContext *s = NULL; |
683
095009fc2f35
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
313 int is_output; |
0 | 314 const char *p; |
315 char buf[256]; | |
2752 | 316 struct sockaddr_storage my_addr; |
683
095009fc2f35
kill warnings patch by (Mns Rullgrd <mru inprovide com>)
michael
parents:
644
diff
changeset
|
317 int len; |
0 | 318 |
319 h->is_streamed = 1; | |
62 | 320 h->max_packet_size = 1472; |
0 | 321 |
322 is_output = (flags & URL_WRONLY); | |
885 | 323 |
2689
7d25b8de708d
Take the target address family in account when determining the family of
lucabe
parents:
2688
diff
changeset
|
324 s = av_mallocz(sizeof(UDPContext)); |
0 | 325 if (!s) |
1787
eb16c64144ee
This fixes error handling for BeOS, removing the need for some ifdefs.
mmu_man
parents:
1754
diff
changeset
|
326 return AVERROR(ENOMEM); |
0 | 327 |
328 h->priv_data = s; | |
329 s->ttl = 16; | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
330 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
|
331 |
0 | 332 p = strchr(uri, '?'); |
333 if (p) { | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
334 s->reuse_socket = find_info_tag(buf, sizeof(buf), "reuse", p); |
0 | 335 if (find_info_tag(buf, sizeof(buf), "ttl", p)) { |
336 s->ttl = strtol(buf, NULL, 10); | |
337 } | |
338 if (find_info_tag(buf, sizeof(buf), "localport", p)) { | |
339 s->local_port = strtol(buf, NULL, 10); | |
340 } | |
62 | 341 if (find_info_tag(buf, sizeof(buf), "pkt_size", p)) { |
342 h->max_packet_size = strtol(buf, NULL, 10); | |
343 } | |
4021
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
344 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
|
345 s->buffer_size = strtol(buf, NULL, 10); |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
346 } |
0 | 347 } |
348 | |
349 /* fill the dest addr */ | |
5775 | 350 ff_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
885 | 351 |
5775 | 352 /* XXX: fix ff_url_split */ |
0 | 353 if (hostname[0] == '\0' || hostname[0] == '?') { |
354 /* only accepts null hostname if input */ | |
3221 | 355 if (flags & URL_WRONLY) |
0 | 356 goto fail; |
357 } else { | |
358 udp_set_remote_url(h, uri); | |
359 } | |
360 | |
2750
b3a11a0966af
Use the same code to set local_port in the IPv4-only case and in the
lucabe
parents:
2744
diff
changeset
|
361 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
|
362 s->local_port = port; |
2752 | 363 udp_fd = udp_socket_create(s, &my_addr, &len); |
0 | 364 if (udp_fd < 0) |
365 goto fail; | |
366 | |
1428
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
367 if (s->reuse_socket) |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
368 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
|
369 goto fail; |
7316227e64eb
Make it possible to reuse UDP socket (optional, disabled by default)
gpoirier
parents:
1358
diff
changeset
|
370 |
0 | 371 /* the bind is needed to give a port to the socket now */ |
4070 | 372 /* if multicast, try the multicast address bind first */ |
373 if (s->is_multicast && !(h->flags & URL_WRONLY)) { | |
374 bind_ret = bind(udp_fd,(struct sockaddr *)&s->dest_addr, len); | |
375 } | |
376 /* bind to the local address if not multicast or if the multicast | |
377 * bind failed */ | |
378 if (bind_ret < 0 && bind(udp_fd,(struct sockaddr *)&my_addr, len) < 0) | |
0 | 379 goto fail; |
380 | |
2751 | 381 len = sizeof(my_addr); |
382 getsockname(udp_fd, (struct sockaddr *)&my_addr, &len); | |
2752 | 383 s->local_port = udp_port(&my_addr, len); |
384 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
385 if (s->is_multicast) { |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
386 if (h->flags & URL_WRONLY) { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
387 /* output */ |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
388 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
|
389 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
390 } else { |
2739
091af9f47edf
Avoid to duplicate the multicast code between the IPv4-only and
lucabe
parents:
2738
diff
changeset
|
391 /* input */ |
2740
e23eaab1a894
Give better names to multicast functions (they are not IPv6-only)
lucabe
parents:
2739
diff
changeset
|
392 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
|
393 goto fail; |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
394 } |
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
395 } |
0 | 396 |
397 if (is_output) { | |
398 /* 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
|
399 tmp = s->buffer_size; |
0 | 400 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &tmp, sizeof(tmp)) < 0) { |
2768 | 401 av_log(NULL, AV_LOG_ERROR, "setsockopt(SO_SNDBUF): %s\n", strerror(errno)); |
0 | 402 goto fail; |
403 } | |
2391 | 404 } else { |
405 /* set udp recv buffer size to the largest possible udp packet size to | |
406 * 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
|
407 tmp = s->buffer_size; |
6390b29b59f2
Allow the UDP socket buffer size to be adjusted using a
andoma
parents:
3776
diff
changeset
|
408 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
|
409 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
|
410 } |
4035
8c161751e4c7
Get rid of MSG_DONTWAIT using a more standard way to use a socket
benoit
parents:
4024
diff
changeset
|
411 /* 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
|
412 ff_socket_nonblock(udp_fd, 1); |
0 | 413 } |
414 | |
415 s->udp_fd = udp_fd; | |
416 return 0; | |
417 fail: | |
418 if (udp_fd >= 0) | |
419 closesocket(udp_fd); | |
420 av_free(s); | |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
421 return AVERROR(EIO); |
0 | 422 } |
423 | |
65 | 424 static int udp_read(URLContext *h, uint8_t *buf, int size) |
0 | 425 { |
426 UDPContext *s = h->priv_data; | |
1332 | 427 int len; |
4024 | 428 fd_set rfds; |
429 int ret; | |
430 struct timeval tv; | |
0 | 431 |
432 for(;;) { | |
4024 | 433 if (url_interrupt_cb()) |
434 return AVERROR(EINTR); | |
435 FD_ZERO(&rfds); | |
436 FD_SET(s->udp_fd, &rfds); | |
437 tv.tv_sec = 0; | |
438 tv.tv_usec = 100 * 1000; | |
439 ret = select(s->udp_fd + 1, &rfds, NULL, NULL, &tv); | |
5896
395592984ef0
Don't report EINTR from select as an error, retry select instead
mstorsjo
parents:
5837
diff
changeset
|
440 if (ret < 0) { |
395592984ef0
Don't report EINTR from select as an error, retry select instead
mstorsjo
parents:
5837
diff
changeset
|
441 if (ff_neterrno() == FF_NETERROR(EINTR)) |
395592984ef0
Don't report EINTR from select as an error, retry select instead
mstorsjo
parents:
5837
diff
changeset
|
442 continue; |
4024 | 443 return AVERROR(EIO); |
5896
395592984ef0
Don't report EINTR from select as an error, retry select instead
mstorsjo
parents:
5837
diff
changeset
|
444 } |
4024 | 445 if (!(ret > 0 && FD_ISSET(s->udp_fd, &rfds))) |
446 continue; | |
4035
8c161751e4c7
Get rid of MSG_DONTWAIT using a more standard way to use a socket
benoit
parents:
4024
diff
changeset
|
447 len = recv(s->udp_fd, buf, size, 0); |
0 | 448 if (len < 0) { |
2056
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
449 if (ff_neterrno() != FF_NETERROR(EAGAIN) && |
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
450 ff_neterrno() != FF_NETERROR(EINTR)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
451 return AVERROR(EIO); |
0 | 452 } else { |
453 break; | |
454 } | |
455 } | |
456 return len; | |
457 } | |
458 | |
65 | 459 static int udp_write(URLContext *h, uint8_t *buf, int size) |
0 | 460 { |
461 UDPContext *s = h->priv_data; | |
462 int ret; | |
463 | |
464 for(;;) { | |
885 | 465 ret = sendto (s->udp_fd, buf, size, 0, |
0 | 466 (struct sockaddr *) &s->dest_addr, |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
467 s->dest_addr_len); |
0 | 468 if (ret < 0) { |
2056
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
469 if (ff_neterrno() != FF_NETERROR(EINTR) && |
eeea52739ff3
use ff_neterrno() and FF_NETERROR() for networking error handling
alex
parents:
1810
diff
changeset
|
470 ff_neterrno() != FF_NETERROR(EAGAIN)) |
2274
b21c2af60bc9
Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents:
2162
diff
changeset
|
471 return AVERROR(EIO); |
0 | 472 } else { |
473 break; | |
474 } | |
475 } | |
476 return size; | |
477 } | |
478 | |
479 static int udp_close(URLContext *h) | |
480 { | |
481 UDPContext *s = h->priv_data; | |
482 | |
579
117ece7c24a6
IPv6 support patch by ("Hans Zandbelt" <Hans.Zandbelt <at> telin {dot} nl>)
michael
parents:
511
diff
changeset
|
483 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
|
484 udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); |
0 | 485 closesocket(s->udp_fd); |
486 av_free(s); | |
487 return 0; | |
488 } | |
489 | |
490 URLProtocol udp_protocol = { | |
491 "udp", | |
492 udp_open, | |
493 udp_read, | |
494 udp_write, | |
495 NULL, /* seek */ | |
496 udp_close, | |
4640
b34d9614b887
Add url_get_file_handle(), which is used to get the file descriptor
rbultje
parents:
4331
diff
changeset
|
497 .url_get_file_handle = udp_get_file_handle, |
0 | 498 }; |