Make tcp proto able to listen

Message ID 1300240359-27440-1-git-send-email-lu_zero@gentoo.org
State Superseded
Headers show

Commit Message

Luca Barbato March 16, 2011, 1:52 a.m.
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
---
 libavformat/tcp.c |   25 +++++++++++++++++++++++--
 1 files changed, 23 insertions(+), 2 deletions(-)

Comments

Ronald Bultje March 16, 2011, 1:54 a.m. | #1
Hi,

On Tue, Mar 15, 2011 at 9:52 PM, Luca Barbato <lu_zero@gentoo.org> wrote:
> 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
> ---
>  libavformat/tcp.c |   25 +++++++++++++++++++++++--
>  1 files changed, 23 insertions(+), 2 deletions(-)

That's really nice, looks OK to me. Maybe an example set of 2 command
lines in protocols.texi?

Ronald
Mans Rullgard March 16, 2011, 1:56 a.m. | #2
Luca Barbato <lu_zero@gentoo.org> writes:

> 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

Funny, I used that exact syntax for my media streaming experiments some
years go.
Luca Barbato March 16, 2011, 2:10 a.m. | #3
On 03/16/2011 02:56 AM, Måns Rullgård wrote:
> Luca Barbato <lu_zero@gentoo.org> writes:
> 
>> 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
> 
> Funny, I used that exact syntax for my media streaming experiments some
> years go.

=)

This patch is part of a larger set aimed at experiment a bit with
protocols and possibly improve the situation.

The same syntax could be shared with other stream and sequence of
packets oriented streams and possibly some of it could be factored.

Still it might be useful as is already.

lu

Patch

diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 83529df..c7eb825 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,12 @@  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) {
         struct pollfd p = {fd, POLLOUT, 0};
         if (ff_neterrno() == AVERROR(EINTR)) {