Re: [FFmpeg-devel] [PATCH 2/3] avformat/tcp: use generic socket API

2017-11-09 Thread Michael Niedermayer
On Thu, Nov 09, 2017 at 04:31:31PM +0700, Nablet Developer wrote:
> this allows to implement other protocols which use
> API similar to BSD sockets (e.g. Haivision SRT)
> 
> Signed-off-by: Nablet Developer 
> ---
>  libavformat/tcp.c | 118 
> +++---

>  libavformat/tcp.h |  59 +++

missing standard inclusion guards

[...]
-- 
Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Does the universe only have a finite lifespan? No, its going to go on
forever, its just that you wont like living in it. -- Hiranya Peiri


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


[FFmpeg-devel] [PATCH 2/3] avformat/tcp: use generic socket API

2017-11-09 Thread Nablet Developer
this allows to implement other protocols which use
API similar to BSD sockets (e.g. Haivision SRT)

Signed-off-by: Nablet Developer 
---
 libavformat/tcp.c | 118 +++---
 libavformat/tcp.h |  59 +++
 2 files changed, 119 insertions(+), 58 deletions(-)
 create mode 100644 libavformat/tcp.h

diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 07b4ed9..a775230 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -32,26 +32,12 @@
 #include 
 #endif
 
-typedef struct TCPContext {
-const AVClass *class;
-int fd;
-int listen;
-int open_timeout;
-int rw_timeout;
-int listen_timeout;
-int recv_buffer_size;
-int send_buffer_size;
-} TCPContext;
-
-#define OFFSET(x) offsetof(TCPContext, x)
+#include "tcp.h"
+
 #define D AV_OPT_FLAG_DECODING_PARAM
 #define E AV_OPT_FLAG_ENCODING_PARAM
 static const AVOption options[] = {
-{ "listen",  "Listen for incoming connections",  OFFSET(listen),   
  AV_OPT_TYPE_INT, { .i64 = 0 }, 0,   2,   .flags = D|E },
-{ "timeout", "set timeout (in microseconds) of socket I/O operations", 
OFFSET(rw_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, 
.flags = D|E },
-{ "listen_timeout",  "Connection awaiting timeout (in milliseconds)",  
OFFSET(listen_timeout), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, 
.flags = D|E },
-{ "send_buffer_size", "Socket send buffer size (in bytes)",
OFFSET(send_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, 
.flags = D|E },
-{ "recv_buffer_size", "Socket receive buffer size (in bytes)", 
OFFSET(recv_buffer_size), AV_OPT_TYPE_INT, { .i64 = -1 }, -1, INT_MAX, 
.flags = D|E },
+TCP_COMMON_OPTS
 { NULL }
 };
 
@@ -63,7 +49,7 @@ static const AVClass tcp_class = {
 };
 
 /* return non zero if error */
-static int tcp_open(URLContext *h, const char *uri, int flags)
+int ff_tcp_open(URLContext *h, const char *uri, int flags)
 {
 struct addrinfo hints = { 0 }, *ai, *cur_ai;
 int port, fd = -1;
@@ -75,10 +61,15 @@ static int tcp_open(URLContext *h, const char *uri, int 
flags)
 char portstr[10];
 s->open_timeout = 500;
 
+s->api = s->api ? s->api : _socket_api;
+s->proto = s->proto ? s->proto : "tcp";
+
 av_url_split(proto, sizeof(proto), NULL, 0, hostname, sizeof(hostname),
 , path, sizeof(path), uri);
-if (strcmp(proto, "tcp"))
+if (strcmp(proto, s->proto)) {
+av_log(h, AV_LOG_ERROR, "incorrect protocol %s %s\n", proto, s->proto);
 return AVERROR(EINVAL);
+}
 if (port <= 0 || port >= 65536) {
 av_log(h, AV_LOG_ERROR, "Port missing in uri\n");
 return AVERROR(EINVAL);
@@ -132,37 +123,42 @@ static int tcp_open(URLContext *h, const char *uri, int 
flags)
 }
 #endif
 
-fd = ff_socket(cur_ai->ai_family,
-   cur_ai->ai_socktype,
-   cur_ai->ai_protocol);
+fd = s->api->socket(cur_ai->ai_family,
+cur_ai->ai_socktype,
+cur_ai->ai_protocol);
 if (fd < 0) {
-ret = ff_neterrno();
+ret = s->api->neterrno();
 goto fail;
 }
 
 /* Set the socket's send or receive buffer sizes, if specified.
If unspecified or setting fails, system default is used. */
 if (s->recv_buffer_size > 0) {
-setsockopt (fd, SOL_SOCKET, SO_RCVBUF, >recv_buffer_size, sizeof 
(s->recv_buffer_size));
+s->api->setsockopt (fd, SOL_SOCKET, SO_RCVBUF, >recv_buffer_size, 
sizeof (s->recv_buffer_size));
 }
 if (s->send_buffer_size > 0) {
-setsockopt (fd, SOL_SOCKET, SO_SNDBUF, >send_buffer_size, sizeof 
(s->send_buffer_size));
+s->api->setsockopt (fd, SOL_SOCKET, SO_SNDBUF, >send_buffer_size, 
sizeof (s->send_buffer_size));
+}
+
+if (s->set_options_pre) {
+if ((ret = s->set_options_pre(h, fd)) < 0)
+goto fail1;
 }
 
 if (s->listen == 2) {
 // multi-client
-if ((ret = ff_listen(fd, cur_ai->ai_addr, cur_ai->ai_addrlen)) < 0)
+if ((ret = ff_listen_ex(s->api, fd, cur_ai->ai_addr, 
cur_ai->ai_addrlen)) < 0)
 goto fail1;
 } else if (s->listen == 1) {
 // single client
-if ((ret = ff_listen_bind(fd, cur_ai->ai_addr, cur_ai->ai_addrlen,
-  s->listen_timeout, h)) < 0)
+if ((ret = ff_listen_bind_ex(s->api, fd, cur_ai->ai_addr, 
cur_ai->ai_addrlen,
+ s->listen_timeout, h)) < 0)
 goto fail1;
 // Socket descriptor already closed here. Safe to overwrite to client 
one.
 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) {
+if ((ret = ff_listen_connect_ex(s->api,