diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-07-30 13:40:05 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-07-30 13:40:05 +0400 |
commit | 42f7c45d7b856839fa613c22645d5bff5352fc87 (patch) | |
tree | 41afdc71546c3d5b52d06df062fb58f59056b3fe /libavformat/udp.c | |
parent | 15ca3ab82531e907c810674fc2c79e5e0b522c74 (diff) | |
parent | 7d99c92945e4b2d12ed2126365482e1900340da0 (diff) |
Merge commit '7d99c92945e4b2d12ed2126365482e1900340da0'
* commit '7d99c92945e4b2d12ed2126365482e1900340da0':
udp: Keep track of include and exclude sources separately
Conflicts:
libavformat/udp.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/udp.c')
-rw-r--r-- | libavformat/udp.c | 86 |
1 files changed, 51 insertions, 35 deletions
diff --git a/libavformat/udp.c b/libavformat/udp.c index 033438869a..9c45254571 100644 --- a/libavformat/udp.c +++ b/libavformat/udp.c @@ -494,6 +494,27 @@ end: } #endif +static int parse_source_list(char *buf, char **sources, int *num_sources, + int max_sources) +{ + char *source_start; + + source_start = buf; + while (1) { + char *next = strchr(source_start, ','); + if (next) + *next = '\0'; + sources[*num_sources] = av_strdup(source_start); + if (!sources[*num_sources]) + return AVERROR(ENOMEM); + source_start = next + 1; + (*num_sources)++; + if (*num_sources >= max_sources || !next) + break; + } + return 0; +} + /* put it in UDP context */ /* return non zero if error */ static int udp_open(URLContext *h, const char *uri, int flags) @@ -507,8 +528,8 @@ static int udp_open(URLContext *h, const char *uri, int flags) struct sockaddr_storage my_addr; socklen_t len; int reuse_specified = 0; - int i, include = 0, num_sources = 0; - char *sources[32]; + int i, num_include_sources = 0, num_exclude_sources = 0; + char *include_sources[32], *exclude_sources[32]; h->is_streamed = 1; @@ -562,24 +583,15 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (av_find_info_tag(buf, sizeof(buf), "localaddr", p)) { av_strlcpy(localaddr, buf, sizeof(localaddr)); } - if (av_find_info_tag(buf, sizeof(buf), "sources", p)) - include = 1; - if (include || av_find_info_tag(buf, sizeof(buf), "block", p)) { - char *source_start; - - source_start = buf; - while (1) { - char *next = strchr(source_start, ','); - if (next) - *next = '\0'; - sources[num_sources] = av_strdup(source_start); - if (!sources[num_sources]) - goto fail; - source_start = next + 1; - num_sources++; - if (num_sources >= FF_ARRAY_ELEMS(sources) || !next) - break; - } + if (av_find_info_tag(buf, sizeof(buf), "sources", p)) { + if (parse_source_list(buf, include_sources, &num_include_sources, + FF_ARRAY_ELEMS(include_sources))) + goto fail; + } + if (av_find_info_tag(buf, sizeof(buf), "block", p)) { + if (parse_source_list(buf, exclude_sources, &num_exclude_sources, + FF_ARRAY_ELEMS(exclude_sources))) + goto fail; } if (!is_output && av_find_info_tag(buf, sizeof(buf), "timeout", p)) s->timeout = strtol(buf, NULL, 10); @@ -648,20 +660,20 @@ static int udp_open(URLContext *h, const char *uri, int flags) } if (h->flags & AVIO_FLAG_READ) { /* input */ - if (num_sources == 0 || !include) { + if (num_include_sources && num_exclude_sources) { + av_log(h, AV_LOG_ERROR, "Simultaneously including and excluding multicast sources is not supported\n"); + goto fail; + } + if (num_include_sources) { + if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, include_sources, num_include_sources, 1) < 0) + goto fail; + } else { if (udp_join_multicast_group(udp_fd, (struct sockaddr *)&s->dest_addr) < 0) goto fail; - - if (num_sources) { - if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 0) < 0) - goto fail; - } - } else if (include && num_sources) { - if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, sources, num_sources, 1) < 0) + } + if (num_exclude_sources) { + if (udp_set_multicast_sources(udp_fd, (struct sockaddr *)&s->dest_addr, s->dest_addr_len, exclude_sources, num_exclude_sources, 0) < 0) goto fail; - } else { - av_log(NULL, AV_LOG_ERROR, "invalid udp settings: inclusive multicast but no sources given\n"); - goto fail; } } } @@ -690,8 +702,10 @@ static int udp_open(URLContext *h, const char *uri, int flags) } } - for (i = 0; i < num_sources; i++) - av_freep(&sources[i]); + for (i = 0; i < num_include_sources; i++) + av_freep(&include_sources[i]); + for (i = 0; i < num_exclude_sources; i++) + av_freep(&exclude_sources[i]); s->udp_fd = udp_fd; @@ -731,8 +745,10 @@ static int udp_open(URLContext *h, const char *uri, int flags) if (udp_fd >= 0) closesocket(udp_fd); av_fifo_free(s->fifo); - for (i = 0; i < num_sources; i++) - av_freep(&sources[i]); + for (i = 0; i < num_include_sources; i++) + av_freep(&include_sources[i]); + for (i = 0; i < num_exclude_sources; i++) + av_freep(&exclude_sources[i]); return AVERROR(EIO); } |