[FFmpeg-devel] [PATCH v2 1/2] lavf/network: add wait fd callback to ff_network_wait_fd_timeout

Zhao Zhili quinkblack at foxmail.com
Mon Feb 8 05:04:15 EET 2021


---
 libavformat/libamqp.c |  4 ++--
 libavformat/network.c | 16 ++++++++++++++--
 libavformat/network.h | 14 +++++++++++++-
 libavformat/tcp.c     |  6 ++++--
 4 files changed, 33 insertions(+), 7 deletions(-)

diff --git a/libavformat/libamqp.c b/libavformat/libamqp.c
index c3b9c484ea..ca7d3ab70f 100644
--- a/libavformat/libamqp.c
+++ b/libavformat/libamqp.c
@@ -241,7 +241,7 @@ static int amqp_proto_write(URLContext *h, const unsigned char *buf, int size)
     amqp_bytes_t message = { size, (void *)buf };
     amqp_basic_properties_t props;
 
-    ret = ff_network_wait_fd_timeout(fd, 1, h->rw_timeout, &h->interrupt_callback);
+    ret = ff_network_wait_fd_timeout(fd, 1, h->rw_timeout, &h->interrupt_callback, NULL);
     if (ret)
         return ret;
 
@@ -270,7 +270,7 @@ static int amqp_proto_read(URLContext *h, unsigned char *buf, int size)
     amqp_rpc_reply_t broker_reply;
     amqp_envelope_t envelope;
 
-    ret = ff_network_wait_fd_timeout(fd, 0, h->rw_timeout, &h->interrupt_callback);
+    ret = ff_network_wait_fd_timeout(fd, 0, h->rw_timeout, &h->interrupt_callback, NULL);
     if (ret)
         return ret;
 
diff --git a/libavformat/network.c b/libavformat/network.c
index 0f5a575f77..48a9af012e 100644
--- a/libavformat/network.c
+++ b/libavformat/network.c
@@ -75,15 +75,27 @@ int ff_network_wait_fd(int fd, int write)
     return ret < 0 ? ff_neterrno() : p.revents & (ev | POLLERR | POLLHUP) ? 0 : AVERROR(EAGAIN);
 }
 
-int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb)
+static int network_wait_fd_callback(int fd, int write, void *opaque) {
+    return ff_network_wait_fd(fd, write);
+}
+
+int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout,
+        AVIOInterruptCB *int_cb, const NetworkWaitFdCB *wait_cb)
 {
     int ret;
     int64_t wait_start = 0;
 
+    const static NetworkWaitFdCB wait_cb_internal = {
+        .wait_fd = network_wait_fd_callback,
+    };
+
+    if (!wait_cb)
+        wait_cb = &wait_cb_internal;
+
     while (1) {
         if (ff_check_interrupt(int_cb))
             return AVERROR_EXIT;
-        ret = ff_network_wait_fd(fd, write);
+        ret = ff_network_wait_fd_cb(wait_cb, fd, write);
         if (ret != AVERROR(EAGAIN))
             return ret;
         if (timeout > 0) {
diff --git a/libavformat/network.h b/libavformat/network.h
index 71347e815b..1a02a6d9ee 100644
--- a/libavformat/network.h
+++ b/libavformat/network.h
@@ -84,6 +84,16 @@ void ff_network_close(void);
 int ff_tls_init(void);
 void ff_tls_deinit(void);
 
+typedef struct NetworkWaitFdCB {
+    int (*wait_fd)(int /*fd*/, int /*write*/, void* /*opaque*/);
+    void *opaque;
+} NetworkWaitFdCB;
+
+static av_always_inline int ff_network_wait_fd_cb(const NetworkWaitFdCB *cb,
+        int fd, int write) {
+    return cb->wait_fd(fd, write, cb->opaque);
+}
+
 int ff_network_wait_fd(int fd, int write);
 
 /**
@@ -94,9 +104,11 @@ int ff_network_wait_fd(int fd, int write);
  * @param write Set 1 to wait for socket able to be read, 0 to be written
  * @param timeout Timeout interval, in microseconds. Actual precision is 100000 mcs, due to ff_network_wait_fd usage
  * @param int_cb Interrupt callback, is checked before each ff_network_wait_fd call
+ * @param wait_cb Wait callback, default implementation is used if NULL
  * @return 0 if data can be read/written, AVERROR(ETIMEDOUT) if timeout expired, or negative error code
  */
-int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout, AVIOInterruptCB *int_cb);
+int ff_network_wait_fd_timeout(int fd, int write, int64_t timeout,
+        AVIOInterruptCB *int_cb, const NetworkWaitFdCB *wait_cb);
 
 /**
  * Waits for up to 'timeout' microseconds. If the usert's int_cb is set and
diff --git a/libavformat/tcp.c b/libavformat/tcp.c
index 2198e0f00e..437eaecbb4 100644
--- a/libavformat/tcp.c
+++ b/libavformat/tcp.c
@@ -237,7 +237,8 @@ static int tcp_read(URLContext *h, uint8_t *buf, int size)
     int ret;
 
     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
-        ret = ff_network_wait_fd_timeout(s->fd, 0, h->rw_timeout, &h->interrupt_callback);
+        ret = ff_network_wait_fd_timeout(s->fd, 0, h->rw_timeout,
+                &h->interrupt_callback, NULL);
         if (ret)
             return ret;
     }
@@ -253,7 +254,8 @@ static int tcp_write(URLContext *h, const uint8_t *buf, int size)
     int ret;
 
     if (!(h->flags & AVIO_FLAG_NONBLOCK)) {
-        ret = ff_network_wait_fd_timeout(s->fd, 1, h->rw_timeout, &h->interrupt_callback);
+        ret = ff_network_wait_fd_timeout(s->fd, 1, h->rw_timeout,
+                &h->interrupt_callback, NULL);
         if (ret)
             return ret;
     }
-- 
2.28.0



More information about the ffmpeg-devel mailing list