You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-10 06:10:52 +02:00
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>
This commit is contained in:
@@ -20,6 +20,7 @@
|
|||||||
|
|
||||||
#include "libavutil/avutil.h"
|
#include "libavutil/avutil.h"
|
||||||
#include "network.h"
|
#include "network.h"
|
||||||
|
#include "url.h"
|
||||||
#include "libavcodec/internal.h"
|
#include "libavcodec/internal.h"
|
||||||
#include "libavutil/mem.h"
|
#include "libavutil/mem.h"
|
||||||
#include "url.h"
|
#include "url.h"
|
||||||
@@ -241,3 +242,50 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
|
|||||||
ff_socket_nonblock(ret, 1);
|
ff_socket_nonblock(ret, 1);
|
||||||
return ret;
|
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;
|
||||||
|
}
|
||||||
|
@@ -28,6 +28,7 @@
|
|||||||
#include "libavutil/error.h"
|
#include "libavutil/error.h"
|
||||||
#include "os_support.h"
|
#include "os_support.h"
|
||||||
#include "avio.h"
|
#include "avio.h"
|
||||||
|
#include "url.h"
|
||||||
|
|
||||||
#if HAVE_UNISTD_H
|
#if HAVE_UNISTD_H
|
||||||
#include <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,
|
int ff_listen_bind(int fd, const struct sockaddr *addr,
|
||||||
socklen_t addrlen, int timeout);
|
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 */
|
#endif /* AVFORMAT_NETWORK_H */
|
||||||
|
@@ -64,7 +64,6 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
const char *p;
|
const char *p;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
int ret;
|
int ret;
|
||||||
socklen_t optlen;
|
|
||||||
char hostname[1024],proto[1024],path[1024];
|
char hostname[1024],proto[1024],path[1024];
|
||||||
char portstr[10];
|
char portstr[10];
|
||||||
h->rw_timeout = 5000000;
|
h->rw_timeout = 5000000;
|
||||||
@@ -121,55 +120,16 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
|
|||||||
goto fail1;
|
goto fail1;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
redo:
|
if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
|
||||||
ff_socket_nonblock(fd, 1);
|
h->rw_timeout, h)) < 0) {
|
||||||
ret = connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen);
|
|
||||||
|
if (ret == AVERROR_EXIT)
|
||||||
|
goto fail1;
|
||||||
|
else
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
h->is_streamed = 1;
|
h->is_streamed = 1;
|
||||||
s->fd = fd;
|
s->fd = fd;
|
||||||
freeaddrinfo(ai);
|
freeaddrinfo(ai);
|
||||||
|
Reference in New Issue
Block a user