diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2013-06-02 10:52:48 +0200 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2013-06-02 11:02:02 +0200 |
commit | 54ddbb477b786be1b90f54bc9aab36cd5babdf7d (patch) | |
tree | 6396225eedd6179882e50cd4aa82d877eeb53da0 /libavformat | |
parent | 4d4f5911d3121133929da7b859755860f93684fd (diff) | |
parent | f849a77e67959eb6a83eb59b784aeefdb98cb80a (diff) | |
download | ffmpeg-streaming-54ddbb477b786be1b90f54bc9aab36cd5babdf7d.zip ffmpeg-streaming-54ddbb477b786be1b90f54bc9aab36cd5babdf7d.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
network: factor out connect-listening code
Conflicts:
libavformat/network.h
libavformat/tcp.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/network.c | 48 | ||||
-rw-r--r-- | libavformat/network.h | 5 | ||||
-rw-r--r-- | libavformat/tcp.c | 52 |
3 files changed, 58 insertions, 47 deletions
diff --git a/libavformat/network.c b/libavformat/network.c index 454ee13..f80f43e 100644 --- a/libavformat/network.c +++ b/libavformat/network.c @@ -20,6 +20,7 @@ #include "libavutil/avutil.h" #include "network.h" +#include "url.h" #include "libavcodec/internal.h" #include "libavutil/mem.h" #include "url.h" @@ -241,3 +242,50 @@ int ff_listen_bind(int fd, const struct sockaddr *addr, ff_socket_nonblock(ret, 1); return ret; } + +int ff_listen_connect(int fd, const struct sockaddr *addr, + socklen_t addrlen, int rw_timeout, URLContext *h) +{ + struct pollfd p = {fd, POLLOUT, 0}; + int64_t wait_started; + int ret; + socklen_t optlen; + + ff_socket_nonblock(fd, 1); + + while ((ret = connect(fd, addr, addrlen))) { + ret = ff_neterrno(); + switch (ret) { + case AVERROR(EINTR): + if (ff_check_interrupt(&h->interrupt_callback)) + return AVERROR_EXIT; + continue; + case AVERROR(EINPROGRESS): + case AVERROR(EAGAIN): + wait_started = av_gettime(); + do { + if (ff_check_interrupt(&h->interrupt_callback)) + return AVERROR_EXIT; + ret = poll(&p, 1, 100); + if (ret > 0) + break; + } while (!rw_timeout || (av_gettime() - wait_started < rw_timeout)); + if (ret <= 0) + return AVERROR(ETIMEDOUT); + optlen = sizeof(ret); + if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen)) + ret = AVUNERROR(ff_neterrno()); + if (ret != 0) { + char errbuf[100]; + ret = AVERROR(ret); + av_strerror(ret, errbuf, sizeof(errbuf)); + av_log(h, AV_LOG_ERROR, + "Connection to %s failed: %s\n", + h->filename, errbuf); + } + default: + return ret; + } + } + return ret; +} diff --git a/libavformat/network.h b/libavformat/network.h index 9335bbc..c6264fd 100644 --- a/libavformat/network.h +++ b/libavformat/network.h @@ -28,6 +28,7 @@ #include "libavutil/error.h" #include "os_support.h" #include "avio.h" +#include "url.h" #if HAVE_UNISTD_H #include <unistd.h> @@ -224,5 +225,7 @@ int ff_is_multicast_address(struct sockaddr *addr); int ff_listen_bind(int fd, const struct sockaddr *addr, socklen_t addrlen, int timeout); - +int ff_listen_connect(int fd, const struct sockaddr *addr, + socklen_t addrlen, int timeout, + URLContext *h); #endif /* AVFORMAT_NETWORK_H */ diff --git a/libavformat/tcp.c b/libavformat/tcp.c index d06c18a..1442f90 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -64,7 +64,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags) const char *p; char buf[256]; int ret; - socklen_t optlen; char hostname[1024],proto[1024],path[1024]; char portstr[10]; h->rw_timeout = 5000000; @@ -121,55 +120,16 @@ static int tcp_open(URLContext *h, const char *uri, int flags) goto fail1; } } else { - redo: - ff_socket_nonblock(fd, 1); - ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen); - } + if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen, + h->rw_timeout, h)) < 0) { - if (ret < 0) { - struct pollfd p = {fd, POLLOUT, 0}; - int64_t wait_started; - ret = ff_neterrno(); - if (ret == AVERROR(EINTR)) { - if (ff_check_interrupt(&h->interrupt_callback)) { - ret = AVERROR_EXIT; + if (ret == AVERROR_EXIT) goto fail1; - } - goto redo; - } - if (ret != AVERROR(EINPROGRESS) && - ret != AVERROR(EAGAIN)) - goto fail; - - /* wait until we are connected or until abort */ - wait_started = av_gettime(); - do { - if (ff_check_interrupt(&h->interrupt_callback)) { - ret = AVERROR_EXIT; - goto fail1; - } - ret = poll(&p, 1, 100); - if (ret > 0) - break; - } while (!h->rw_timeout || (av_gettime() - wait_started < h->rw_timeout)); - if (ret <= 0) { - ret = AVERROR(ETIMEDOUT); - goto fail; - } - /* test error */ - optlen = sizeof(ret); - if (getsockopt (fd, SOL_SOCKET, SO_ERROR, &ret, &optlen)) - ret = AVUNERROR(ff_neterrno()); - if (ret != 0) { - char errbuf[100]; - ret = AVERROR(ret); - av_strerror(ret, errbuf, sizeof(errbuf)); - av_log(h, AV_LOG_ERROR, - "TCP connection to %s:%d failed: %s\n", - hostname, port, errbuf); - goto fail; + else + goto fail; } } + h->is_streamed = 1; s->fd = fd; freeaddrinfo(ai); |