diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-04-08 04:50:13 +0400 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-04-08 04:50:13 +0400 |
commit | c88caa522c41cd4108d39d8dd98805e867606ae3 (patch) | |
tree | 90eacfa0065bb907cd6543f5b2865d31d3d0a677 /libavformat/tcp.c | |
parent | db95e559f2b1c392295b09e8457d6f161eb5acdb (diff) | |
parent | a2031251c7eedd0d82cb9e08717990fa2ae6299f (diff) |
Merge remote branch 'qatar/master'
* qatar/master:
proto: include os_support.h in network.h
matroskaenc: don't write an empty Cues element.
lavc: add a FF_API_REQUEST_CHANNELS deprecation macro
avio: move extern url_interrupt_cb declaration from avio.h to url.h
avio: make av_register_protocol2 internal.
avio: avio_ prefix for url_set_interrupt_cb.
avio: AVIO_ prefixes for URL_ open flags.
proto: introduce listen option in tcp
doc: clarify configure features
proto: factor ff_network_wait_fd and use it on udp
Conflicts:
ffmpeg.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat/tcp.c')
-rw-r--r-- | libavformat/tcp.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/libavformat/tcp.c b/libavformat/tcp.c index fb94b63984..f0d1c4556f 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -19,10 +19,12 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avformat.h" +#include "libavutil/parseutils.h" #include <unistd.h> #include "internal.h" #include "network.h" #include "os_support.h" +#include "url.h" #if HAVE_POLL_H #include <poll.h> #endif @@ -38,6 +40,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags) struct addrinfo hints, *ai, *cur_ai; int port, fd = -1; TCPContext *s = NULL; + int listen_socket = 0; + const char *p; + char buf[256]; int ret; socklen_t optlen; char hostname[1024],proto[1024],path[1024]; @@ -48,6 +53,11 @@ static int tcp_open(URLContext *h, const char *uri, int flags) if (strcmp(proto,"tcp") || port <= 0 || port >= 65536) return AVERROR(EINVAL); + p = strchr(uri, '?'); + if (p) { + if (av_find_info_tag(buf, sizeof(buf), "listen", p)) + listen_socket = 1; + } memset(&hints, 0, sizeof(hints)); hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; @@ -66,10 +76,21 @@ static int tcp_open(URLContext *h, const char *uri, int flags) fd = socket(cur_ai->ai_family, cur_ai->ai_socktype, cur_ai->ai_protocol); if (fd < 0) goto fail; - ff_socket_nonblock(fd, 1); + if (listen_socket) { + int fd1; + ret = bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); + listen(fd, 1); + fd1 = accept(fd, NULL, NULL); + closesocket(fd); + fd = fd1; + } else { redo: - ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); + ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); + } + + ff_socket_nonblock(fd, 1); + if (ret < 0) { int timeout=50; struct pollfd p = {fd, POLLOUT, 0}; @@ -138,23 +159,13 @@ static int tcp_open(URLContext *h, const char *uri, int flags) return ret; } -static int tcp_wait_fd(int fd, int write) -{ - int ev = write ? POLLOUT : POLLIN; - struct pollfd p = { .fd = fd, .events = ev, .revents = 0 }; - int ret; - - ret = poll(&p, 1, 100); - return ret < 0 ? ff_neterrno() : p.revents & ev ? 0 : AVERROR(EAGAIN); -} - static int tcp_read(URLContext *h, uint8_t *buf, int size) { TCPContext *s = h->priv_data; int ret; - if (!(h->flags & URL_FLAG_NONBLOCK)) { - ret = tcp_wait_fd(s->fd, 0); + if (!(h->flags & AVIO_FLAG_NONBLOCK)) { + ret = ff_network_wait_fd(s->fd, 0); if (ret < 0) return ret; } @@ -167,8 +178,8 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size) TCPContext *s = h->priv_data; int ret; - if (!(h->flags & URL_FLAG_NONBLOCK)) { - ret = tcp_wait_fd(s->fd, 1); + if (!(h->flags & AVIO_FLAG_NONBLOCK)) { + ret = ff_network_wait_fd(s->fd, 1); if (ret < 0) return ret; } |