diff options
author | Luca Barbato <lu_zero@gentoo.org> | 2011-03-04 01:41:22 +0100 |
---|---|---|
committer | Luca Barbato <lu_zero@gentoo.org> | 2011-04-07 02:54:30 +0200 |
commit | 3d42d4937b029b604da7d53dce16c72e8edde29c (patch) | |
tree | 19bc74ae8986e15617855955aaa71265ce8d05b9 | |
parent | a013291d26d325ba81d8db758d5e5adccc743cf5 (diff) | |
download | ffmpeg-streaming-3d42d4937b029b604da7d53dce16c72e8edde29c.zip ffmpeg-streaming-3d42d4937b029b604da7d53dce16c72e8edde29c.tar.gz |
proto: introduce listen option in tcp
This way is possible to have simple micro-server act like
ffmpeg -i file.nut -vcodec copy -acodec copy -f nut tcp://foo:1234?listen
-rw-r--r-- | doc/protocols.texi | 17 | ||||
-rw-r--r-- | libavformat/tcp.c | 24 |
2 files changed, 39 insertions, 2 deletions
diff --git a/doc/protocols.texi b/doc/protocols.texi index 83c238f..18749ef 100644 --- a/doc/protocols.texi +++ b/doc/protocols.texi @@ -402,6 +402,23 @@ ffplay sap://[ff0e::2:7ffe] Trasmission Control Protocol. +The required syntax for a TCP url is: +@example +tcp://@var{hostname}:@var{port}[?@var{options}] +@end example + +@table @option + +@item listen +Listen for an incoming connection + +@example +ffmpeg -i @var{input} -f @var{format} tcp://@var{hostname}:@var{port}?listen +ffplay tcp://@var{hostname}:@var{port} +@end example + +@end table + @section udp User Datagram Protocol. diff --git a/libavformat/tcp.c b/libavformat/tcp.c index cf294dc..51074c0 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -19,6 +19,7 @@ * 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" @@ -38,6 +39,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 +52,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 +75,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) { struct pollfd p = {fd, POLLOUT, 0}; if (ff_neterrno() == AVERROR(EINTR)) { |