On Fri, Jun 26, 2015 at 10:51 AM, Nicolas George <geo...@nsup.org> wrote:
> Le septidi 7 messidor, an CCXXIII, Stephan Holljes a écrit :
>> Thanks, I understand the datastructures and their interaction a lot
>> better now. I discussed it with a friend yesterday too and there a lot
>> of the things started to make more sense.
>> I'm currently working on the implementation, when questions arise I
>> will ask again.
>
> Good. Please try to pose a WIP patch today to make sure you are really in
> the right track.
>
> Regards,
>
> --
>   Nicolas George
>
> _______________________________________________
> ffmpeg-devel mailing list
> ffmpeg-devel@ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/ffmpeg-devel
>

I think I implemented everything necessary, but I don't know how to
test it. The old behaviour of accepting a single client is now also
broken. How do I detect which behaviour the user wants? Should I
introduce a new option for http and tcp connections or make the listen
field take more values than just 0 and 1?
Attached are patches with the changes I made so far. It compiles, but
breaks http server capabilities for now.
From 22f958ad8d0058865c94847ca8cd2488e2a61c9e Mon Sep 17 00:00:00 2001
From: Stephan Holljes <klaxa1...@googlemail.com>
Date: Fri, 26 Jun 2015 20:48:49 +0200
Subject: [PATCH 1/6] lavf/network: split ff_listen_bind into ff_listen and
 ff_accept

Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com>
---
 libavformat/network.c | 27 +++++++++++++++++++++------
 libavformat/network.h |  4 ++++
 2 files changed, 25 insertions(+), 6 deletions(-)

diff --git a/libavformat/network.c b/libavformat/network.c
index 47ade8c..8d61746 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -187,12 +187,11 @@ int ff_socket(int af, int type, int proto)
     return fd;
 }
 
-int ff_listen_bind(int fd, const struct sockaddr *addr,
-                   socklen_t addrlen, int timeout, URLContext *h)
+int ff_listen(int fd, const struct sockaddr *addr,
+              socklen_t addrlen)
 {
     int ret;
     int reuse = 1;
-    struct pollfd lp = { fd, POLLIN, 0 };
     if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))) {
         av_log(NULL, AV_LOG_WARNING, "setsockopt(SO_REUSEADDR) failed\n");
     }
@@ -203,6 +202,13 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
     ret = listen(fd, 1);
     if (ret)
         return ff_neterrno();
+    return ret;
+}
+
+int ff_accept(int fd, int timeout, URLContext *h)
+{
+    int ret;
+    struct pollfd lp = { fd, POLLIN, 0 };
 
     ret = ff_poll_interrupt(&lp, 1, timeout, &h->interrupt_callback);
     if (ret < 0)
@@ -211,15 +217,24 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
     ret = accept(fd, NULL, NULL);
     if (ret < 0)
         return ff_neterrno();
-
-    closesocket(fd);
-
     if (ff_socket_nonblock(ret, 1) < 0)
         av_log(NULL, AV_LOG_DEBUG, "ff_socket_nonblock failed\n");
 
     return ret;
 }
 
+int ff_listen_bind(int fd, const struct sockaddr *addr,
+                   socklen_t addrlen, int timeout, URLContext *h)
+{
+    int ret;
+    if ((ret = ff_listen(fd, addr, addrlen)) < 0)
+        return ret;
+    ret = ff_accept(fd, timeout, h);
+    closesocket(fd);
+    return ret;
+
+}
+
 int ff_listen_connect(int fd, const struct sockaddr *addr,
                       socklen_t addrlen, int timeout, URLContext *h,
                       int will_try_next)
diff --git a/libavformat/network.h b/libavformat/network.h
index 86fb656..44e109c 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -254,6 +254,10 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
                    socklen_t addrlen, int timeout,
                    URLContext *h);
 
+int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen);
+
+int ff_accept(int fd, int timeout, URLContext *h);
+
 /**
  * Connect to a file descriptor and poll for result.
  *
-- 
2.1.0

From 4d0b5e42882f180d76a3a64da96dc87bf0ba0635 Mon Sep 17 00:00:00 2001
From: Stephan Holljes <klaxa1...@googlemail.com>
Date: Fri, 26 Jun 2015 20:50:35 +0200
Subject: [PATCH 2/6] lavf/avio: add ffurl_accept

Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com>
---
 libavformat/avio.c | 5 +++++
 libavformat/url.h  | 9 +++++++++
 2 files changed, 14 insertions(+)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index aff8d10..153230f 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -211,6 +211,11 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
     return 0;
 }
 
+int ffurl_accept(URLContext *sc, URLContext *cc)
+{
+    return sc->prot->url_accept(sc, cc);
+}
+
 #define URL_SCHEME_CHARS                        \
     "abcdefghijklmnopqrstuvwxyz"                \
     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"                \
diff --git a/libavformat/url.h b/libavformat/url.h
index 99a3201..34fdea2 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -58,6 +58,7 @@ typedef struct URLProtocol {
      * for those nested protocols.
      */
     int     (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options);
+    int     (*url_accept)(URLContext *s, URLContext *c);
 
     /**
      * Read data from the protocol.
@@ -140,6 +141,14 @@ int ffurl_open(URLContext **puc, const char *filename, int flags,
                const AVIOInterruptCB *int_cb, AVDictionary **options);
 
 /**
+ * Accept an URLContext c on an URLContext s
+ * @param  s server context
+ * @param  c client context
+ * @return 0 on success, ff_neterrno() on failure.
+ */
+int ffurl_accept(URLContext *s, URLContext *c);
+
+/**
  * Read up to size bytes from the resource accessed by h, and store
  * the read bytes in buf.
  *
-- 
2.1.0

From 4a2f643af7cc5a7692a6267f484ba3f8d0363066 Mon Sep 17 00:00:00 2001
From: Stephan Holljes <klaxa1...@googlemail.com>
Date: Fri, 26 Jun 2015 20:51:26 +0200
Subject: [PATCH 3/6] lavf/avio: add avio_accept

Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com>
---
 libavformat/avio.h    |  1 +
 libavformat/aviobuf.c | 12 ++++++++++++
 2 files changed, 13 insertions(+)

diff --git a/libavformat/avio.h b/libavformat/avio.h
index 5ac5d38..f688851 100644
--- a/libavformat/avio.h
+++ b/libavformat/avio.h
@@ -648,4 +648,5 @@ struct AVBPrint;
  */
 int avio_read_to_bprint(AVIOContext *h, struct AVBPrint *pb, size_t max_size);
 
+int avio_accept(AVIOContext *s, AVIOContext **c);
 #endif /* AVFORMAT_AVIO_H */
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index ff85081..dcdc1a4 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -1021,6 +1021,18 @@ int avio_read_to_bprint(AVIOContext *h, AVBPrint *pb, size_t max_size)
     return 0;
 }
 
+int avio_accept(AVIOContext *s, AVIOContext **c) {
+    URLContext *sc = s->opaque;
+    URLContext *cc;
+    int ret;
+    if ((ret = ffurl_open(&cc, sc->filename, AVIO_FLAG_READ_WRITE, &sc->interrupt_callback, NULL)) < 0)
+        return ret;
+    if ((ret = ffio_fdopen(c, cc)) < 0)
+        return ret;
+    ret = ffurl_accept(sc, cc);
+    return ret;
+}
+
 /* output in a dynamic buffer */
 
 typedef struct DynBuffer {
-- 
2.1.0

From 8e83b82efb5ae26296bed8244fba1fd93b978f48 Mon Sep 17 00:00:00 2001
From: Stephan Holljes <klaxa1...@googlemail.com>
Date: Fri, 26 Jun 2015 20:55:58 +0200
Subject: [PATCH 4/6] lavf/tcp: make tcp_open return with a listening socket
 without calling accept()

Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com>
---
 libavformat/tcp.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index f24cad2..04210b3 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -126,11 +126,9 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
     }
 
     if (s->listen) {
-        if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
-                                  s->listen_timeout, h)) < 0) {
+        if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0) {
             goto fail1;
         }
-        fd = ret;
     } else {
         if ((ret = ff_listen_connect(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
                                      s->open_timeout / 1000, h, !!cur_ai->ai_next)) < 0) {
-- 
2.1.0

From 418fcd63d8e5ff721ba38763f3677d1b5be6396b Mon Sep 17 00:00:00 2001
From: Stephan Holljes <klaxa1...@googlemail.com>
Date: Fri, 26 Jun 2015 20:56:27 +0200
Subject: [PATCH 5/6] lavf/tcp: add tcp_accept

Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com>
---
 libavformat/tcp.c | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 04210b3..588e602 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -161,6 +161,20 @@ static int tcp_open(URLContext *h, const char *uri, int flags)
     return ret;
 }
 
+static int tcp_accept(URLContext *s, URLContext *c)
+{
+    TCPContext *sc = s->priv_data;
+    TCPContext *cc = c->priv_data;
+    int ret;
+    ret = accept(sc->fd, NULL, NULL);
+    if (ret < 0) {
+        return ff_neterrno();
+    }
+    cc->fd = ret;
+    return 0;
+
+}
+
 static int tcp_read(URLContext *h, uint8_t *buf, int size)
 {
     TCPContext *s = h->priv_data;
@@ -221,6 +235,7 @@ static int tcp_get_file_handle(URLContext *h)
 URLProtocol ff_tcp_protocol = {
     .name                = "tcp",
     .url_open            = tcp_open,
+    .url_accept          = tcp_accept,
     .url_read            = tcp_read,
     .url_write           = tcp_write,
     .url_close           = tcp_close,
-- 
2.1.0

From 88632fa0d54a68c8876e8024c76ead5245be73d1 Mon Sep 17 00:00:00 2001
From: Stephan Holljes <klaxa1...@googlemail.com>
Date: Fri, 26 Jun 2015 20:58:56 +0200
Subject: [PATCH 6/6] lavf/http: add http_accept and move connection logic to
 it, since ffurl_open in http_listen returns without a connected client

Signed-off-by: Stephan Holljes <klaxa1...@googlemail.com>
---
 libavformat/http.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index 676bfd5..65ac507 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -320,11 +320,10 @@ static int http_listen(URLContext *h, const char *uri, int flags,
                        AVDictionary **options) {
     HTTPContext *s = h->priv_data;
     int ret;
-    static const char header[] = "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n";
     char hostname[1024], proto[10];
     char lower_url[100];
     const char *lower_proto = "tcp";
-    int port, new_location;
+    int port;
     s->chunked_post = 1;
     av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname), &port,
                  NULL, 0, uri);
@@ -336,12 +335,6 @@ static int http_listen(URLContext *h, const char *uri, int flags,
     if ((ret = ffurl_open(&s->hd, lower_url, AVIO_FLAG_READ_WRITE,
                           &h->interrupt_callback, options)) < 0)
         goto fail;
-    if ((ret = http_read_header(h, &new_location)) < 0)
-         goto fail;
-    if ((ret = ffurl_write(s->hd, header, strlen(header))) < 0)
-         goto fail;
-    return 0;
-
 fail:
     handle_http_errors(h, ret);
     av_dict_free(&s->chained_options);
@@ -382,6 +375,25 @@ static int http_open(URLContext *h, const char *uri, int flags,
     return ret;
 }
 
+static int http_accept(URLContext *s, URLContext *c)
+{
+    int ret, new_location;
+    static const char header[] = "HTTP/1.1 200 OK\r\nContent-Type: application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n";
+    HTTPContext *sh = s->priv_data;
+    HTTPContext *ch = c->priv_data;
+    URLContext *sl = sh->hd;
+    URLContext *cl = ch->hd;
+    if ((ret = ffurl_accept(sl, cl)) < 0)
+        goto fail;
+    if ((ret = http_read_header(s, &new_location)) < 0)
+        goto fail;
+    if ((ret = ffurl_write(sl, header, strlen(header))) < 0)
+        goto fail;
+fail:
+    handle_http_errors(s, ret);
+    return ret;
+}
+
 static int http_getc(HTTPContext *s)
 {
     int len;
@@ -1477,6 +1489,7 @@ static int http_proxy_write(URLContext *h, const uint8_t *buf, int size)
 URLProtocol ff_httpproxy_protocol = {
     .name                = "httpproxy",
     .url_open            = http_proxy_open,
+    .url_accept          = http_accept,
     .url_read            = http_buf_read,
     .url_write           = http_proxy_write,
     .url_close           = http_proxy_close,
-- 
2.1.0

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to