diff -rNu ffmpeg-0.7.1/configure ffmpeg-0.7.1.new/configure
|
old
|
new
|
|
| 1109 | 1109 | strerror_r |
| 1110 | 1110 | strtok_r |
| 1111 | 1111 | struct_addrinfo |
| | 1112 | struct_ifreq |
| 1112 | 1113 | struct_ipv6_mreq |
| 1113 | 1114 | struct_sockaddr_in6 |
| 1114 | 1115 | struct_sockaddr_sa_len |
| … |
… |
|
| 1116 | 1117 | symver |
| 1117 | 1118 | symver_gnu_asm |
| 1118 | 1119 | symver_asm_label |
| | 1120 | sys_ioctl_h |
| 1119 | 1121 | sys_mman_h |
| 1120 | 1122 | sys_resource_h |
| 1121 | 1123 | sys_select_h |
| … |
… |
|
| 2801 | 2803 | check_type netinet/in.h "struct ipv6_mreq" -D_DARWIN_C_SOURCE |
| 2802 | 2804 | check_type netinet/in.h "struct sockaddr_in6" |
| 2803 | 2805 | check_type "sys/types.h sys/socket.h" "struct sockaddr_storage" |
| | 2806 | check_type net/if.h "struct ifreq" -D_SVID_SOURCE |
| 2804 | 2807 | check_struct "sys/types.h sys/socket.h" "struct sockaddr" sa_len |
| | 2808 | check_header sys/ioctl.h |
| 2805 | 2809 | # Prefer arpa/inet.h over winsock2 |
| 2806 | 2810 | if check_header arpa/inet.h ; then |
| 2807 | 2811 | check_func closesocket |
diff -rNu ffmpeg-0.7.1/libavformat/network.h ffmpeg-0.7.1.new/libavformat/network.h
|
old
|
new
|
|
| 56 | 56 | #define ff_neterrno() AVERROR(errno) |
| 57 | 57 | #endif |
| 58 | 58 | |
| | 59 | #if HAVE_STRUCT_IFREQ |
| | 60 | #include <net/if.h> |
| | 61 | #endif |
| | 62 | |
| | 63 | #if HAVE_SYS_IOCTL_H |
| | 64 | #include <sys/ioctl.h> |
| | 65 | #endif |
| | 66 | |
| 59 | 67 | #if HAVE_ARPA_INET_H |
| 60 | 68 | #include <arpa/inet.h> |
| 61 | 69 | #endif |
diff -rNu ffmpeg-0.7.1/libavformat/udp.c ffmpeg-0.7.1.new/libavformat/udp.c
|
old
|
new
|
|
| 30 | 30 | #include "avio_internal.h" |
| 31 | 31 | #include "libavutil/parseutils.h" |
| 32 | 32 | #include "libavutil/fifo.h" |
| | 33 | #include "libavutil/avstring.h" |
| 33 | 34 | #include <unistd.h> |
| 34 | 35 | #include "internal.h" |
| 35 | 36 | #include "network.h" |
| … |
… |
|
| 55 | 56 | int local_port; |
| 56 | 57 | int reuse_socket; |
| 57 | 58 | struct sockaddr_storage dest_addr; |
| | 59 | struct in_addr if_addr; |
| 58 | 60 | int dest_addr_len; |
| 59 | 61 | int is_connected; |
| 60 | 62 | |
| … |
… |
|
| 92 | 94 | return 0; |
| 93 | 95 | } |
| 94 | 96 | |
| 95 | | static int udp_join_multicast_group(int sockfd, struct sockaddr *addr) |
| | 97 | static int udp_join_multicast_group(int sockfd, struct sockaddr *addr, struct in_addr *ifaddr) |
| 96 | 98 | { |
| 97 | 99 | #ifdef IP_ADD_MEMBERSHIP |
| 98 | 100 | if (addr->sa_family == AF_INET) { |
| 99 | 101 | struct ip_mreq mreq; |
| 100 | 102 | |
| 101 | 103 | mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; |
| 102 | | mreq.imr_interface.s_addr= INADDR_ANY; |
| | 104 | mreq.imr_interface.s_addr= ifaddr->s_addr; |
| 103 | 105 | if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
| 104 | 106 | av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_ADD_MEMBERSHIP): %s\n", strerror(errno)); |
| 105 | 107 | return -1; |
| … |
… |
|
| 121 | 123 | return 0; |
| 122 | 124 | } |
| 123 | 125 | |
| 124 | | static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr) |
| | 126 | static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr, struct in_addr *ifaddr) |
| 125 | 127 | { |
| 126 | 128 | #ifdef IP_DROP_MEMBERSHIP |
| 127 | 129 | if (addr->sa_family == AF_INET) { |
| 128 | 130 | struct ip_mreq mreq; |
| 129 | 131 | |
| 130 | 132 | mreq.imr_multiaddr.s_addr = ((struct sockaddr_in *)addr)->sin_addr.s_addr; |
| 131 | | mreq.imr_interface.s_addr= INADDR_ANY; |
| | 133 | mreq.imr_interface.s_addr= ifaddr->s_addr; |
| 132 | 134 | if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (const void *)&mreq, sizeof(mreq)) < 0) { |
| 133 | 135 | av_log(NULL, AV_LOG_ERROR, "setsockopt(IP_DROP_MEMBERSHIP): %s\n", strerror(errno)); |
| 134 | 136 | return -1; |
| … |
… |
|
| 246 | 248 | * get the local port first, then you must call this function to set |
| 247 | 249 | * the remote server address. |
| 248 | 250 | * |
| 249 | | * url syntax: udp://host:port[?option=val...] |
| | 251 | * url syntax: udp://multicastinterface@host:port[?option=val...] |
| | 252 | * multicastinterface@ is optional |
| | 253 | * multicastinterface is ether the name or the ip of the interface |
| 250 | 254 | * option: 'ttl=n' : set the ttl value (for multicast only) |
| 251 | 255 | * 'localport=n' : set the local port |
| 252 | 256 | * 'pkt_size=n' : set max packet size |
| … |
… |
|
| 259 | 263 | int ff_udp_set_remote_url(URLContext *h, const char *uri) |
| 260 | 264 | { |
| 261 | 265 | UDPContext *s = h->priv_data; |
| 262 | | char hostname[256], buf[10]; |
| | 266 | char hostname[256], buf[10], ifaddr[256]; |
| 263 | 267 | int port; |
| 264 | 268 | const char *p; |
| 265 | 269 | |
| 266 | | av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &port, NULL, 0, uri); |
| | 270 | av_url_split(NULL, 0, ifaddr, sizeof(ifaddr), hostname, sizeof(hostname), &port, NULL, 0, uri); |
| 267 | 271 | |
| 268 | 272 | /* set the destination address */ |
| 269 | 273 | s->dest_addr_len = udp_set_url(&s->dest_addr, hostname, port); |
| … |
… |
|
| 271 | 275 | return AVERROR(EIO); |
| 272 | 276 | } |
| 273 | 277 | s->is_multicast = ff_is_multicast_address((struct sockaddr*) &s->dest_addr); |
| | 278 | if (s->is_multicast) { |
| | 279 | if (!*ifaddr) |
| | 280 | s->if_addr.s_addr=INADDR_ANY; |
| | 281 | else if (!inet_aton(ifaddr,&s->if_addr)) { |
| | 282 | #if defined(HAVE_STRUCT_IFREQ) && defined(HAVE_SYS_IOCTL_H) && defined(SIOCGIFADDR) |
| | 283 | int sock_fd; |
| | 284 | struct ifreq ifr; |
| | 285 | |
| | 286 | memset(&ifr,0,sizeof(ifr)); |
| | 287 | av_strlcpy(ifr.ifr_name,ifaddr,sizeof(ifr.ifr_name)); |
| | 288 | sock_fd=socket(AF_INET, SOCK_DGRAM, 0); |
| | 289 | if (sock_fd==-1) |
| | 290 | return AVERROR(EIO); |
| | 291 | if (ioctl(sock_fd, SIOCGIFADDR, &ifr) == -1) { |
| | 292 | close(sock_fd); |
| | 293 | return AVERROR(EIO); |
| | 294 | } |
| | 295 | close(sock_fd); |
| | 296 | s->if_addr=((struct sockaddr_in *)(&ifr.ifr_addr))->sin_addr; |
| | 297 | #else |
| | 298 | return AVERROR(EIO); |
| | 299 | #endif |
| | 300 | } |
| | 301 | } |
| 274 | 302 | p = strchr(uri, '?'); |
| 275 | 303 | if (p) { |
| 276 | 304 | if (av_find_info_tag(buf, sizeof(buf), "connect", p)) { |
| … |
… |
|
| 483 | 511 | goto fail; |
| 484 | 512 | } else { |
| 485 | 513 | /* input */ |
| 486 | | if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) |
| | 514 | if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr,&s->if_addr) < 0) |
| 487 | 515 | goto fail; |
| 488 | 516 | } |
| 489 | 517 | } |
| … |
… |
|
| 601 | 629 | UDPContext *s = h->priv_data; |
| 602 | 630 | |
| 603 | 631 | if (s->is_multicast && !(h->flags & AVIO_WRONLY)) |
| 604 | | udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr); |
| | 632 | udp_leave_multicast_group(s->udp_fd, (struct sockaddr *)&s->dest_addr, &s->if_addr); |
| 605 | 633 | closesocket(s->udp_fd); |
| 606 | 634 | av_fifo_free(s->fifo); |
| 607 | 635 | av_free(s); |