]> git.sesse.net Git - ffmpeg/commitdiff
avio: Add an option 'rw_timeout'
authorAndrey Utkin <andrey.krieger.utkin@gmail.com>
Mon, 27 Aug 2012 13:31:08 +0000 (16:31 +0300)
committerMartin Storsjö <martin@martin.st>
Thu, 24 Mar 2016 08:33:50 +0000 (10:33 +0200)
If set non-zero, this limits duration of the retry_transfer_wrapper()
loop, thus affecting ffurl_read*(), ffurl_write(). As soon as
one single byte is successfully received/transmitted, the timer
restarts.

This has further changes by Michael Niedermayer and Martin Storsjö.

Signed-off-by: Martin Storsjö <martin@martin.st>
doc/protocols.texi
libavformat/avio.c
libavformat/url.h
libavformat/version.h

index f30567d83990862df6e103906f51be8cf97d78fb..c0663ac76a71d9ba6028d17067d392b26b416eb9 100644 (file)
@@ -17,6 +17,14 @@ particular protocol using the option
 The option "-protocols" of the av* tools will display the list of
 supported protocols.
 
+All protocols accept the following options:
+
+@table @option
+@item rw_timeout
+Maximum time to wait for (network) read/write operations to complete,
+in microseconds.
+@end table
+
 A description of the currently available protocols follows.
 
 @section concat
index 4da6b7416504787df7fd30e53822f3ae1301750c..60399909904df2e3c513d42a2290b4f3e32b63d3 100644 (file)
@@ -49,7 +49,10 @@ static void *urlcontext_child_next(void *obj, void *prev)
     return NULL;
 }
 
-static const AVOption options[] = { { NULL } };
+static const AVOption options[] = {
+    { "rw_timeout", "Timeout for IO operations (in microseconds)", offsetof(URLContext, rw_timeout), AV_OPT_TYPE_INT64, { .i64 = 0 }, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_DECODING_PARAM },
+    { NULL }
+};
 const AVClass ffurl_context_class = {
     .class_name       = "URLContext",
     .item_name        = urlcontext_to_name,
@@ -199,6 +202,7 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
 {
     int ret, len;
     int fast_retries = 5;
+    int64_t wait_since = 0;
 
     len = 0;
     while (len < size_min) {
@@ -209,14 +213,23 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
             return ret;
         if (ret == AVERROR(EAGAIN)) {
             ret = 0;
-            if (fast_retries)
+            if (fast_retries) {
                 fast_retries--;
-            else
+            } else {
+                if (h->rw_timeout) {
+                    if (!wait_since)
+                        wait_since = av_gettime_relative();
+                    else if (av_gettime_relative() > wait_since + h->rw_timeout)
+                        return AVERROR(EIO);
+                }
                 av_usleep(1000);
+            }
         } else if (ret < 1)
             return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
-        if (ret)
+        if (ret) {
             fast_retries = FFMAX(fast_retries, 2);
+            wait_since = 0;
+        }
         len += ret;
         if (ff_check_interrupt(&h->interrupt_callback))
             return AVERROR_EXIT;
index 482658b7feda8a6b6918914dd43c59327b959f24..408c674ddff015572c78b5c688f8c20f6b361955 100644 (file)
@@ -49,6 +49,7 @@ typedef struct URLContext {
     int is_streamed;            /**< true if streamed (no seek possible), default = false */
     int is_connected;
     AVIOInterruptCB interrupt_callback;
+    int64_t rw_timeout;         /**< maximum time to wait for (network) read/write operation completion, in microseconds */
 } URLContext;
 
 typedef struct URLProtocol {
index f264076f39fdba28e78f739c28af6a641e324862..75d765b3e64f222bd8a504431b44c0d061452e07 100644 (file)
@@ -31,7 +31,7 @@
 
 #define LIBAVFORMAT_VERSION_MAJOR 57
 #define LIBAVFORMAT_VERSION_MINOR  5
-#define LIBAVFORMAT_VERSION_MICRO  0
+#define LIBAVFORMAT_VERSION_MICRO  1
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \