39 #ifndef IPV6_ADD_MEMBERSHIP 40 #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP 41 #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP 61 #define UDP_TX_BUF_SIZE 32768 62 #define UDP_MAX_PKT_SIZE 65536 64 #define OFFSET(x) offsetof(UDPContext, x) 65 #define D AV_OPT_FLAG_DECODING_PARAM 66 #define E AV_OPT_FLAG_ENCODING_PARAM 68 {
"ttl",
"Time to live (in milliseconds, multicast only)",
OFFSET(
ttl),
AV_OPT_TYPE_INT, { .i64 = 16 }, 0, INT_MAX, .flags =
D|
E },
91 av_log(ctx, level,
"%s: %s\n", prefix, errbuf);
95 struct sockaddr *addr)
97 #ifdef IP_MULTICAST_TTL 98 if (addr->sa_family == AF_INET) {
99 if (setsockopt(sockfd, IPPROTO_IP, IP_MULTICAST_TTL, &mcastTTL,
sizeof(mcastTTL)) < 0) {
105 #if defined(IPPROTO_IPV6) && defined(IPV6_MULTICAST_HOPS) 106 if (addr->sa_family == AF_INET6) {
107 if (setsockopt(sockfd, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, &mcastTTL,
sizeof(mcastTTL)) < 0) {
118 #ifdef IP_ADD_MEMBERSHIP 119 if (addr->sa_family == AF_INET) {
122 mreq.imr_multiaddr.s_addr = ((
struct sockaddr_in *)addr)->sin_addr.s_addr;
123 mreq.imr_interface.s_addr= INADDR_ANY;
124 if (setsockopt(sockfd, IPPROTO_IP, IP_ADD_MEMBERSHIP, (
const void *)&mreq,
sizeof(mreq)) < 0) {
130 #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) 131 if (addr->sa_family == AF_INET6) {
132 struct ipv6_mreq mreq6;
134 memcpy(&mreq6.ipv6mr_multiaddr, &(((
struct sockaddr_in6 *)addr)->sin6_addr),
sizeof(
struct in6_addr));
135 mreq6.ipv6mr_interface= 0;
147 #ifdef IP_DROP_MEMBERSHIP 148 if (addr->sa_family == AF_INET) {
151 mreq.imr_multiaddr.s_addr = ((
struct sockaddr_in *)addr)->sin_addr.s_addr;
152 mreq.imr_interface.s_addr= INADDR_ANY;
153 if (setsockopt(sockfd, IPPROTO_IP, IP_DROP_MEMBERSHIP, (
const void *)&mreq,
sizeof(mreq)) < 0) {
159 #if HAVE_STRUCT_IPV6_MREQ && defined(IPPROTO_IPV6) 160 if (addr->sa_family == AF_INET6) {
161 struct ipv6_mreq mreq6;
163 memcpy(&mreq6.ipv6mr_multiaddr, &(((
struct sockaddr_in6 *)addr)->sin6_addr),
sizeof(
struct in6_addr));
164 mreq6.ipv6mr_interface= 0;
175 const char *hostname,
int port,
176 int type,
int family,
int flags)
178 struct addrinfo hints = { 0 }, *res = 0;
181 const char *node = 0, *service =
"0";
184 snprintf(sport,
sizeof(sport),
"%d", port);
187 if ((hostname) && (hostname[0] !=
'\0') && (hostname[0] !=
'?')) {
193 if ((error =
getaddrinfo(node, service, &hints, &res))) {
196 node ? node :
"unknown",
197 service ? service :
"unknown",
205 int sockfd,
struct sockaddr *addr,
207 int nb_sources,
int include)
209 #if HAVE_STRUCT_GROUP_SOURCE_REQ && defined(MCAST_BLOCK_SOURCE) && !defined(_WIN32) 213 for (i = 0; i < nb_sources; i++) {
214 struct group_source_req mreqs;
215 int level = addr->sa_family == AF_INET ? IPPROTO_IP : IPPROTO_IPV6;
217 SOCK_DGRAM, AF_UNSPEC,
222 mreqs.gsr_interface = 0;
223 memcpy(&mreqs.gsr_group, addr, addr_len);
227 if (setsockopt(sockfd, level,
228 include ? MCAST_JOIN_SOURCE_GROUP : MCAST_BLOCK_SOURCE,
229 (
const void *)&mreqs,
sizeof(mreqs)) < 0) {
237 #elif HAVE_STRUCT_IP_MREQ_SOURCE && defined(IP_BLOCK_SOURCE) 239 if (addr->sa_family != AF_INET) {
241 "Setting multicast sources only supported for IPv4\n");
244 for (i = 0; i < nb_sources; i++) {
245 struct ip_mreq_source mreqs;
247 SOCK_DGRAM, AF_UNSPEC,
251 if (sourceaddr->
ai_addr->sa_family != AF_INET) {
258 mreqs.imr_multiaddr.s_addr = ((
struct sockaddr_in *)addr)->sin_addr.s_addr;
259 mreqs.imr_interface.s_addr = INADDR_ANY;
260 mreqs.imr_sourceaddr.s_addr = ((
struct sockaddr_in *)sourceaddr->
ai_addr)->sin_addr.s_addr;
263 if (setsockopt(sockfd, IPPROTO_IP,
264 include ? IP_ADD_SOURCE_MEMBERSHIP : IP_BLOCK_SOURCE,
265 (
const void *)&mreqs,
sizeof(mreqs)) < 0) {
280 const char *hostname,
int port)
286 if (res0 == 0)
return AVERROR(EIO);
295 socklen_t *addr_len,
const char *
localaddr)
300 int family = AF_UNSPEC;
302 if (((
struct sockaddr *) &s->
dest_addr)->sa_family)
303 family = ((
struct sockaddr *) &s->
dest_addr)->sa_family;
309 for (res = res0; res; res=res->
ai_next) {
310 udp_fd =
ff_socket(res->ai_family, SOCK_DGRAM, 0);
311 if (udp_fd != -1)
break;
318 memcpy(addr, res->ai_addr, res->ai_addrlen);
319 *addr_len = res->ai_addrlen;
335 char sbuf[
sizeof(int)*3+1];
343 return strtol(sbuf,
NULL, 10);
365 char hostname[256], buf[10];
377 p = strchr(uri,
'?');
425 char *next = strchr(source_start,
',');
428 sources[*num_sources] =
av_strdup(source_start);
429 if (!sources[*num_sources])
431 source_start = next + 1;
433 if (*num_sources >= max_sources || !next)
443 char hostname[1024],
localaddr[1024] =
"";
444 int port,
udp_fd = -1,
tmp, bind_ret = -1;
451 int i, num_include_sources = 0, num_exclude_sources = 0;
452 char *include_sources[32], *exclude_sources[32];
464 &num_include_sources,
478 p = strchr(uri,
'?');
488 s->
ttl = strtol(buf,
NULL, 10);
503 av_strlcpy(localaddr, buf,
sizeof(localaddr));
521 if (hostname[0] ==
'\0' || hostname[0] ==
'?') {
554 bind_ret = bind(udp_fd,(
struct sockaddr *)&s->
dest_addr, len);
559 if (bind_ret < 0 && bind(udp_fd,(
struct sockaddr *)&my_addr, len) < 0) {
564 len =
sizeof(my_addr);
565 getsockname(udp_fd, (
struct sockaddr *)&my_addr, &len);
576 if (num_include_sources && num_exclude_sources) {
577 av_log(h,
AV_LOG_ERROR,
"Simultaneously including and excluding multicast sources is not supported\n");
580 if (num_include_sources) {
585 num_include_sources, 1) < 0)
591 if (num_exclude_sources) {
596 num_exclude_sources, 0) < 0)
605 if (setsockopt(udp_fd, SOL_SOCKET, SO_SNDBUF, &
tmp,
sizeof(
tmp)) < 0) {
613 if (setsockopt(udp_fd, SOL_SOCKET, SO_RCVBUF, &
tmp,
sizeof(
tmp)) < 0) {
626 for (i = 0; i < num_include_sources; i++)
628 for (i = 0; i < num_exclude_sources; i++)
636 for (i = 0; i < num_include_sources; i++)
638 for (i = 0; i < num_exclude_sources; i++)
653 ret = recv(s->
udp_fd, buf, size, 0);
669 ret = sendto (s->
udp_fd, buf, size, 0,
673 ret = send(s->
udp_fd, buf, size, 0);
697 .priv_data_class = &udp_class,
static int udp_open(URLContext *h, const char *uri, int flags)
void av_url_split(char *proto, int proto_size, char *authorization, int authorization_size, char *hostname, int hostname_size, int *port_ptr, char *path, int path_size, const char *url)
Split a URL string into components.
static int udp_set_multicast_sources(URLContext *h, int sockfd, struct sockaddr *addr, int addr_len, char **sources, int nb_sources, int include)
static void log_net_error(void *ctx, int level, const char *prefix)
#define URL_PROTOCOL_FLAG_NETWORK
#define AV_LOG_WARNING
Something somehow does not look correct.
int is_streamed
true if streamed (no seek possible), default = false
static int parse_source_list(char *buf, char **sources, int *num_sources, int max_sources)
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
#define AVIO_FLAG_READ
read-only
static int udp_set_url(URLContext *h, struct sockaddr_storage *addr, const char *hostname, int port)
#define AVIO_FLAG_WRITE
write-only
#define FF_ARRAY_ELEMS(a)
int ff_socket(int af, int type, int proto)
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
miscellaneous OS support macros and functions.
int ff_udp_get_local_port(URLContext *h)
Return the local port used by the UDP connection.
static int udp_port(struct sockaddr_storage *addr, int addr_len)
int av_find_info_tag(char *arg, int arg_size, const char *tag1, const char *info)
Attempt to find a specific tag in a URL.
static int udp_close(URLContext *h)
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
int ff_udp_set_remote_url(URLContext *h, const char *uri)
If no filename is given to av_open_input_file because you want to get the local port first...
static struct addrinfo * udp_resolve_host(URLContext *h, const char *hostname, int port, int type, int family, int flags)
int ff_is_multicast_address(struct sockaddr *addr)
size_t av_strlcpy(char *dst, const char *src, size_t size)
Copy the string src to dst, but no more than size - 1 bytes, and null-terminate dst.
static const AVOption options[]
static int udp_get_file_handle(URLContext *h)
Return the udp file handle for select() usage to wait for several RTP streams at the same time...
int ff_socket_nonblock(int socket, int enable)
static int udp_leave_multicast_group(int sockfd, struct sockaddr *addr)
#define IPV6_ADD_MEMBERSHIP
char * av_strdup(const char *s)
Duplicate the string s.
#define AVIO_FLAG_NONBLOCK
Use non-blocking mode.
#define IPV6_DROP_MEMBERSHIP
Describe the class of an AVClass context structure.
int av_strerror(int errnum, char *errbuf, size_t errbuf_size)
Put a description of the AVERROR code errnum in errbuf.
struct sockaddr_storage dest_addr
static int udp_read(URLContext *h, uint8_t *buf, int size)
struct addrinfo * ai_next
static int udp_set_multicast_ttl(int sockfd, int mcastTTL, struct sockaddr *addr)
static int udp_socket_create(URLContext *h, struct sockaddr_storage *addr, socklen_t *addr_len, const char *localaddr)
int max_packet_size
if non zero, the stream is packetized with this max packet size
static const AVClass udp_class
int ff_network_wait_fd(int fd, int write)
unbuffered private I/O API
static int udp_join_multicast_group(int sockfd, struct sockaddr *addr)
struct sockaddr * ai_addr
static int udp_write(URLContext *h, const uint8_t *buf, int size)
const URLProtocol ff_udp_protocol