Re: [FFmpeg-devel] GSoC update

2015-07-08 Thread Stephan Holljes
Hi,

I have moved the client code in the sample application into a separate
function, I hope I did this correctly. I also annotated the patch
files with the changes that occurred over the past few iterations of
these exchanges. They will be sent shortly as git send-email patches.

I also tested the sample application numerous times with wget, nc and
siege. I also constantly tested that sending data as a POST client
still works (with wget).

Regards,
Stephan
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] GSoC update

2015-07-03 Thread Nicolas George
Le quintidi 15 messidor, an CCXXIII, Stephan Holljes a écrit :
  +if ((ret = ffurl_alloc(c, s-filename, AVIO_FLAG_READ_WRITE, 
  sl-interrupt_callback))  0)
  AVIO_FLAG_READ_WRITE seems wrong.
 Changed to AVIO_FLAG_WRITE, but don't we read the request data from
 the client? Why does it work as intended with AVIO_FLAG_WRITE?

You are mixing the modes for the HTTP context and for the TCP context.

For the TCP context, it must be READ_WRITE, of course, in order to read the
request and send the reply.

But for the HTTP context, it only determines what methods are automatically
accepted by the logic you wrote a bit earlier: GET to write to clients, POST
to read from clients.

 Since I was told on IRC that sending git send-email patches is
 preferred over attached patch-files, I will send the patches in a
 series of follow-up emails.

I will look at them presently.

Regards,

-- 
  Nicolas George


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] GSoC update

2015-07-02 Thread Stephan Holljes
On Wed, Jul 1, 2015 at 4:10 PM, Nicolas George geo...@nsup.org wrote:
 Le duodi 12 messidor, an CCXXIII, Stephan Holljes a écrit :
 This might be a stupid question, but how would I go about that? Just
 use open() and read() from stdio.h or are there structs that allow me
 to do that even more easily?

 You must use the avio family of function, not the OS functions directly. You
 can have a look at tools/aviocat.c, it is rather simple and does a good
 chunk of what your server needs to do per client.

 From b0f0caa700b8cbd0352304de703d8191bf0ac922 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Tue, 30 Jun 2015 07:42:14 +0200
 Subject: [PATCH 1/8] 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 | 21 +
  2 files changed, 42 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;

 I believe you are slightly changing the behaviour here: in the old code, if
 accept() fails, the server is not closed.

 +
 +}
 +
  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..e684787 100644
 --- a/libavformat/network.h
 +++ b/libavformat/network.h
 @@ -255,6 +255,27 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
 URLContext *h);

  /**

 + * Bind to a file descriptor and return a listening socket without 
 accepting connections.
 + * @param fd  First argument of bind().
 + * @param addrSecond argument of bind().
 + * @param addrlen Third argument of bind().
 + * @returnA blocking file descriptor on success
 + *or an AVERROR on failure.

 I believe the summary and @return statements are wrong: the new code always
 returns 0 for success, which is fine.

 + */
 +int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen);
 +
 +/**
 + * Poll for a single connection on the passed file descriptor.
 + * @param fd  The listening socket file descriptor.
 + * @param timeout Polling timeout in milliseconds.
 + * @param h   URLContext providing interrupt check
 + *callback and logging context.
 + * @returnA non-blocking file descriptor on success
 + *or an AVERROR on failure.
 + */
 +int ff_accept(int fd, int timeout, URLContext *h);
 +
 +/**
   * Connect to a file descriptor and poll for result.
   *
   * @param fd   First argument of connect(),
 --
 2.1.0


 From 330c0eedaede961e52a4a4d93b2211156bc15a69 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Tue, 30 Jun 2015 08:16:37 +0200
 Subject: [PATCH 2/8] lavf/avio: add ffurl_accept and ffurl_handshake

 Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
 ---
  libavformat/avio.c | 17 +
  libavformat/url.h  | 18 ++
  2 files changed, 35 insertions(+)

 diff --git a/libavformat/avio.c b/libavformat/avio.c
 index c188adc..63c8b75 100644
 --- a/libavformat/avio.c
 +++ b/libavformat/avio.c
 @@ -211,6 +211,23 @@ int ffurl_connect(URLContext *uc, 

Re: [FFmpeg-devel] GSoC update

2015-07-01 Thread Nicolas George
Le duodi 12 messidor, an CCXXIII, Stephan Holljes a écrit :
 This might be a stupid question, but how would I go about that? Just
 use open() and read() from stdio.h or are there structs that allow me
 to do that even more easily?

You must use the avio family of function, not the OS functions directly. You
can have a look at tools/aviocat.c, it is rather simple and does a good
chunk of what your server needs to do per client.

 From b0f0caa700b8cbd0352304de703d8191bf0ac922 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Tue, 30 Jun 2015 07:42:14 +0200
 Subject: [PATCH 1/8] 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 | 21 +
  2 files changed, 42 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;

I believe you are slightly changing the behaviour here: in the old code, if
accept() fails, the server is not closed.

 +
 +}
 +
  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..e684787 100644
 --- a/libavformat/network.h
 +++ b/libavformat/network.h
 @@ -255,6 +255,27 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
 URLContext *h);
  
  /**

 + * Bind to a file descriptor and return a listening socket without accepting 
 connections.
 + * @param fd  First argument of bind().
 + * @param addrSecond argument of bind().
 + * @param addrlen Third argument of bind().
 + * @returnA blocking file descriptor on success
 + *or an AVERROR on failure.

I believe the summary and @return statements are wrong: the new code always
returns 0 for success, which is fine.

 + */
 +int ff_listen(int fd, const struct sockaddr *addr, socklen_t addrlen);
 +
 +/**
 + * Poll for a single connection on the passed file descriptor.
 + * @param fd  The listening socket file descriptor.
 + * @param timeout Polling timeout in milliseconds.
 + * @param h   URLContext providing interrupt check
 + *callback and logging context.
 + * @returnA non-blocking file descriptor on success
 + *or an AVERROR on failure.
 + */
 +int ff_accept(int fd, int timeout, URLContext *h);
 +
 +/**
   * Connect to a file descriptor and poll for result.
   *
   * @param fd   First argument of connect(),
 -- 
 2.1.0
 

 From 330c0eedaede961e52a4a4d93b2211156bc15a69 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Tue, 30 Jun 2015 08:16:37 +0200
 Subject: [PATCH 2/8] lavf/avio: add ffurl_accept and ffurl_handshake
 
 Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
 ---
  libavformat/avio.c | 17 +
  libavformat/url.h  | 18 ++
  2 files changed, 35 insertions(+)
 
 diff --git a/libavformat/avio.c b/libavformat/avio.c
 index c188adc..63c8b75 100644
 --- a/libavformat/avio.c
 +++ b/libavformat/avio.c
 @@ -211,6 +211,23 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
  return 0;
  }
  
 +int 

Re: [FFmpeg-devel] GSoC update

2015-06-28 Thread Nicolas George
Le decadi 10 messidor, an CCXXIII, Stephan Holljes a écrit :
 Hi,
 attached patches are the current state of work.
 It's probably still a bit rough around the edges, but I think I made
 some progress.
 The sample code in doc/examples does not write any data as of yet, but
 the HTTP handshake works.

A few quick remarks, without entering into the fine details since the patch
series will likely evolve still quite a bit.

 From b43aeaa27f6ca7df476aa194b2f78aa1b49516d0 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Sun, 28 Jun 2015 06:06:16 +0200
 Subject: [PATCH 01/10] 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(-)

This one looks good to me, except a small doxy would be nice for the two new
functions.

 From 39faa1ea315bb51452446e291fd5d93d7eb3a988 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Sun, 28 Jun 2015 06:12:37 +0200
 Subject: [PATCH 02/10] lavf/avio: add ffurl_accept and ffurl_handshake
 
 Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
 ---
  libavformat/avio.c | 15 +++
  libavformat/url.h  | 12 
  2 files changed, 27 insertions(+)

ffurl_accept() requires two arguments, but I suspect ffurl_handshake() only
requires one, the client. A doxy would be nice for ffurl_handshake().

Also, the client argument of ffurl_accept() and url_accept() should probably
a pointer to pointer, like ffurl_alloc(), so that it can allocate the
context itself.

 From 8b473ba9acffecf98f8252eeccb413bcfbbf38c5 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Sun, 28 Jun 2015 06:13:36 +0200
 Subject: [PATCH 03/10] lavf/avio: add avio_accept and avio_handshake
 
 Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
 ---
  libavformat/avio.h|  2 ++
  libavformat/aviobuf.c | 21 +
  2 files changed, 23 insertions(+)

That part looks mostly good.

 From 8ba3d1ef528cdd9209764b0f696b8df81ea46870 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Sun, 28 Jun 2015 06:16:02 +0200
 Subject: [PATCH 04/10] lavf/http: add http_accept and http_handshake
 
 Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
 ---
  libavformat/http.c | 38 ++
  1 file changed, 38 insertions(+)

I believe this patch can not come before the one for TCP.

 
 diff --git a/libavformat/http.c b/libavformat/http.c
 index 676bfd5..7219f08 100644
 --- a/libavformat/http.c
 +++ b/libavformat/http.c
 @@ -382,6 +382,38 @@ static int http_open(URLContext *h, const char *uri, int 
 flags,
  return ret;
  }
  
 +static int http_accept(URLContext *s, URLContext *c)
 +{
 +int ret;
 +HTTPContext *sh = s-priv_data;
 +HTTPContext *ch = c-priv_data;
 +URLContext *sl = sh-hd;
 +URLContext *cl;

 +if ((ret = ffurl_alloc(cl, sl-filename, AVIO_FLAG_READ_WRITE, 
 sl-interrupt_callback))  0)
 +goto fail;
 +if ((ret = ffurl_accept(sl, cl))  0)
 +goto fail;
 +ch-hd = cl;
 +fail:
 +return ret;
 +}

This looks mostly correct, but I suspect it would be more convenient to make
url_accept() responsible for allocating the client context. Otherwise, the
application is responsible for allocating a client context with the correct
protocol and settings, this is fragile.

 +
 +static int http_handshake(URLContext *s, URLContext *c) {
 +int ret, err, new_location;
 +HTTPContext *sh = s-priv_data;
 +HTTPContext *ch = c-priv_data;
 +URLContext *sl = sh-hd;
 +URLContext *cl = ch-hd;
 +static const char header[] = HTTP/1.1 200 OK\r\nContent-Type: 
 application/octet-stream\r\nTransfer-Encoding: chunked\r\n\r\n;
 +if ((err = http_read_header(c, new_location))  0)
 +goto fail;
 +if ((ret = ffurl_write(cl, header, strlen(header)))  0)
 +goto fail;
 +fail:
 +handle_http_errors(c, err);
 +return ret;
 +}

As you can see, the s argument is never used.

Also, it should probably call ffurl_handshake() on the underlying socket:
for TCP it is a nop, but for TLS, for example, it is blocking.

 +
  static int http_getc(HTTPContext *s)
  {
  int len;
 @@ -1346,6 +1378,8 @@ HTTP_CLASS(http);
  URLProtocol ff_http_protocol = {
  .name= http,
  .url_open2   = http_open,
 +.url_accept  = http_accept,
 +.url_handshake   = http_handshake,
  .url_read= http_read,
  .url_write   = http_write,
  .url_seek= http_seek,
 @@ -1364,6 +1398,8 @@ HTTP_CLASS(https);
  URLProtocol ff_https_protocol = {
  .name= https,
  .url_open2   = http_open,
 +.url_accept  = http_accept,
 +.url_handshake   = http_handshake,
  .url_read 

Re: [FFmpeg-devel] GSoC update

2015-06-27 Thread Stephan Holljes
Hi,
attached patches are the current state of work.
It's probably still a bit rough around the edges, but I think I made
some progress.
The sample code in doc/examples does not write any data as of yet, but
the HTTP handshake works.
From b43aeaa27f6ca7df476aa194b2f78aa1b49516d0 Mon Sep 17 00:00:00 2001
From: Stephan Holljes klaxa1...@googlemail.com
Date: Sun, 28 Jun 2015 06:06:16 +0200
Subject: [PATCH 01/10] 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 39faa1ea315bb51452446e291fd5d93d7eb3a988 Mon Sep 17 00:00:00 2001
From: Stephan Holljes klaxa1...@googlemail.com
Date: Sun, 28 Jun 2015 06:12:37 +0200
Subject: [PATCH 02/10] lavf/avio: add ffurl_accept and ffurl_handshake

Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
---
 libavformat/avio.c | 15 +++
 libavformat/url.h  | 12 
 2 files changed, 27 insertions(+)

diff --git a/libavformat/avio.c b/libavformat/avio.c
index aff8d10..cb8126d 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -211,6 +211,21 @@ int ffurl_connect(URLContext *uc, AVDictionary **options)
 return 0;
 }
 
+int ffurl_accept(URLContext *s, URLContext *c)
+{
+int ret;
+if ((ret = s-prot-url_accept(s, c))  0)
+return ret;
+c-is_connected = 1;
+return ret;
+
+}
+
+int ffurl_handshake(URLContext *s, URLContext *c)
+{
+return s-prot-url_handshake(s, c);
+}
+
 #define URL_SCHEME_CHARS\
 abcdefghijklmnopqrstuvwxyz\
 ABCDEFGHIJKLMNOPQRSTUVWXYZ\
diff --git a/libavformat/url.h b/libavformat/url.h
index 99a3201..78613c5 100644
--- a/libavformat/url.h
+++ b/libavformat/url.h
@@ -58,6 +58,8 @@ 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);
+int (*url_handshake)(URLContext *s, URLContext *c);
 
 /**
  * Read data from the protocol.
@@ -140,6 +142,16 @@ 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 the accepted filedescriptor on success, ff_neterrno() on failure.
+ */
+int ffurl_accept(URLContext *s, URLContext *c);
+
+int 

Re: [FFmpeg-devel] GSoC update

2015-06-26 Thread Nicolas George
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


signature.asc
Description: Digital signature
___
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel


Re: [FFmpeg-devel] GSoC update

2015-06-26 Thread Nicolas George
L'octidi 8 messidor, an CCXXIII, Stephan Holljes a écrit :
 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.

Since that behaviour was already established, breaking it without notice is
not an option :(

 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?

Increasing the range for listen is a good idea.

I am afraid it will make the accept functions a but awkward, having to work
with either two contexts (server and client) or only one (server that will
become client).

 Attached are patches with the changes I made so far. It compiles, but
 breaks http server capabilities for now.

To actually test multi-client code, it will be necessary to write a
multi-client sample application. Fortunately, that should not be very hard.


 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 

Re: [FFmpeg-devel] GSoC update

2015-06-26 Thread Stephan Holljes
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 

Re: [FFmpeg-devel] GSoC update

2015-06-23 Thread Nicolas George
This has better go to the mailing list.

Le quintidi 5 messidor, an CCXXIII, Stephan Holljes a écrit :
 So far I have split ff_listen_bind() into ff_listen_bind() and
 ff_accept() and added an url_accept field to URLProtocol (see attached
 patch).

I do not believe this is the correct approach. ff_listen_bind() is an
internal helper that works specifically for sockets.

 I read our past exchanges for a number of times and I am somewhat at a
 loss as to where to allocate my additional Client(-Contexts).
 No sourcefile I have looked at stores multiple AVIOContexts or
 AVFormatContexts (or I have not seen it).
 I also could not find out how ffmpeg would even accept multiple
 clients. The ff_listen_bind() call is blocking on accept() and it is
 only called once.
 Maybe I'm also overlooking some documentation. Maybe I am also looking
 in the wrong place. The files I have looked at the most have been:
 url.h network.c/h, avio.c/h aviobuf.c and tcp.c.

You need to understand very well how it happens for plain Unix TCP clients.

First, the server create and prepares the server socket s, with socket(),
bind() and mostly listen(). There is also a list of client sockets c[i],
initially empty.

Then, indefinitely and in parallel:

  * call accept() on s: this returns a new c[i] added to the list;

  * perform read() / write() on each c[i], remove them from the list if they
are finished.

Here, in parallel means either threads, forked processes, or emulated
parallelism with poll() and non-blocking operations. For lavf, non-blocking
operations do not work, so you can assume parallelism between multiple
clients is achieved with threads; although I very much would like that all
new networking code is input-driven and therefore ready for non-blocking.

Now, as for how to transpose it into lavf terms:

* Creating and preparing the server socket: avio_open2() with various
  options for the address and the listen option set.

* Accepting a new client: a new function that you have to design, probably
  avio_accept().

There are a few caveats for avio_accept():

* Creating a new AVFormatContext, like accept() creates a new socket. That
  is not really difficult, IMHO. It just means the API will look somewhat
  like that:

  int avio_accept(AVIOContext *s, AVIOContext **c, ...);

  The c parameter is just like the s parameter to avio_open2(): it allocates
  a new context if necessary and populates it.

* Except, the current API accepts a single client by replacing the server
  context. This must still be possible after the change. Maybe just
  overwriting the server context will work, but it must be considered.

* If you remember, a full TCP accept() requires three handshake packets: SYN
  from the client, ACK-SYN from the server and then ACK from the client. The
  kernel handles this in the background and accept() returns a new client
  only when the full handshake is done. In lavf, we do not have a kernel
  working in the background, so it must be explicit.

  We can look at how non-blocking connect() works: first call connect() on
  the socket, it returns EINPROGRESS immediately, the repeatedly call
  getsockopt(SO_ERROR) to check the status of the connection until it stops
  returning EAGAIN.

  I believe we can do the same: avio_accept(s, c) to initiate the accept,
  and then avio_accept_connect(c) or something (feel free to suggest better
  names) to finish the handshake.

  For the particular case of the HTTP server, the avio_accept() part would
  call avio_accept() on the underlying socket (or TLS context), and the
  avio_accept_connect() would call avio_accept_connect() on the underlying
  context and then perform the handshake.

  In terms of application, the code would probably look something like this
  (error checks and stuff removed):

  av_dict_set(options, listen, 1);
  avio_open2(server, http://:8080;, options);
  while (1) {
  avio_accept(server, client);
  thread_run {
  avio_accept_connect(client);
  communicate_with_the_client(client);
  avio_close(client);
  };
  }

Hope this helps.

Regards,

-- 
  Nicolas George

 From 234199a18e0c3bfede5f04a9ade0a11c71061285 Mon Sep 17 00:00:00 2001
 From: Stephan Holljes klaxa1...@googlemail.com
 Date: Tue, 23 Jun 2015 16:41:51 +0200
 Subject: [PATCH] lavf: Split ff_listen_bind into ff_listen_bind and ff_accept
  and implement its usage in tcp.
 
 Signed-off-by: Stephan Holljes klaxa1...@googlemail.com
 ---
  libavformat/network.c |  7 ---
  libavformat/network.h | 12 +++-
  libavformat/tcp.c | 10 ++
  libavformat/url.h |  1 +
  4 files changed, 26 insertions(+), 4 deletions(-)
 
 diff --git a/libavformat/network.c b/libavformat/network.c
 index 47ade8c..8d9434f 100644
 --- a/libavformat/network.c
 +++ b/libavformat/network.c

 @@ -204,10 +204,11 @@ int ff_listen_bind(int fd, const struct sockaddr *addr,
  if (ret)
  return ff_neterrno();
  
 -ret = ff_poll_interrupt(lp, 1, timeout, 

Re: [FFmpeg-devel] GSoC update

2015-06-23 Thread Stephan Holljes
Thank you for the detailed reply. It has helped me understand the
structures a lot better than before.
Comments inline.

On Tue, Jun 23, 2015 at 5:25 PM, Nicolas George geo...@nsup.org wrote:
 This has better go to the mailing list.

 Le quintidi 5 messidor, an CCXXIII, Stephan Holljes a écrit :
 So far I have split ff_listen_bind() into ff_listen_bind() and
 ff_accept() and added an url_accept field to URLProtocol (see attached
 patch).

 I do not believe this is the correct approach. ff_listen_bind() is an
 internal helper that works specifically for sockets.

 I read our past exchanges for a number of times and I am somewhat at a
 loss as to where to allocate my additional Client(-Contexts).
 No sourcefile I have looked at stores multiple AVIOContexts or
 AVFormatContexts (or I have not seen it).
 I also could not find out how ffmpeg would even accept multiple
 clients. The ff_listen_bind() call is blocking on accept() and it is
 only called once.
 Maybe I'm also overlooking some documentation. Maybe I am also looking
 in the wrong place. The files I have looked at the most have been:
 url.h network.c/h, avio.c/h aviobuf.c and tcp.c.

 You need to understand very well how it happens for plain Unix TCP clients.

 First, the server create and prepares the server socket s, with socket(),
 bind() and mostly listen(). There is also a list of client sockets c[i],
 initially empty.

 Then, indefinitely and in parallel:

   * call accept() on s: this returns a new c[i] added to the list;

   * perform read() / write() on each c[i], remove them from the list if they
 are finished.

 Here, in parallel means either threads, forked processes, or emulated
 parallelism with poll() and non-blocking operations. For lavf, non-blocking
 operations do not work, so you can assume parallelism between multiple
 clients is achieved with threads; although I very much would like that all
 new networking code is input-driven and therefore ready for non-blocking.

 Now, as for how to transpose it into lavf terms:

 * Creating and preparing the server socket: avio_open2() with various
   options for the address and the listen option set.

Am I correct to understand that this has to return immediately,
because if avio_open2() does not return, I have no (server)
AVIOContext to call avio_accept() with?
The HTTPContext will then not have any clients connected to it, which
is different from the current behaviour.


 * Accepting a new client: a new function that you have to design, probably
   avio_accept().

 There are a few caveats for avio_accept():

 * Creating a new AVFormatContext, like accept() creates a new socket. That
   is not really difficult, IMHO. It just means the API will look somewhat
   like that:

   int avio_accept(AVIOContext *s, AVIOContext **c, ...);

   The c parameter is just like the s parameter to avio_open2(): it allocates
   a new context if necessary and populates it.

 * Except, the current API accepts a single client by replacing the server
   context. This must still be possible after the change. Maybe just
   overwriting the server context will work, but it must be considered.

 * If you remember, a full TCP accept() requires three handshake packets: SYN
   from the client, ACK-SYN from the server and then ACK from the client. The
   kernel handles this in the background and accept() returns a new client
   only when the full handshake is done. In lavf, we do not have a kernel
   working in the background, so it must be explicit.

   We can look at how non-blocking connect() works: first call connect() on
   the socket, it returns EINPROGRESS immediately, the repeatedly call
   getsockopt(SO_ERROR) to check the status of the connection until it stops
   returning EAGAIN.

   I believe we can do the same: avio_accept(s, c) to initiate the accept,
   and then avio_accept_connect(c) or something (feel free to suggest better
   names) to finish the handshake.

   For the particular case of the HTTP server, the avio_accept() part would
   call avio_accept() on the underlying socket (or TLS context), and the
   avio_accept_connect() would call avio_accept_connect() on the underlying
   context and then perform the handshake.

   In terms of application, the code would probably look something like this
   (error checks and stuff removed):

   av_dict_set(options, listen, 1);
   avio_open2(server, http://:8080;, options);
   while (1) {
   avio_accept(server, client);
   thread_run {
   avio_accept_connect(client);
   communicate_with_the_client(client);
   avio_close(client);
   };
   }

Would this still be in http.c? If my thinking is correct, this should
be in http_open() then, but only if http_listen() returns without
accepting an initial client.


 Hope this helps.

 Regards,

 --
   Nicolas George


A lot of this I still can't wrap my head around. I am still not sure
about a lot of things, for example how and where to use threading to
serve clients in parallel, or