diff options
author | Andrey Utkin <andrey.krieger.utkin@gmail.com> | 2012-08-27 16:31:08 +0300 |
---|---|---|
committer | Martin Storsjö <martin@martin.st> | 2016-03-24 10:33:50 +0200 |
commit | ccea588f831906084b8c8235222920e6984beb72 (patch) | |
tree | 571171710e83cbfc7f3842d4d053b5bb0023b478 /libavformat | |
parent | d44f3e4059506a182f59218b1e967d42b01e097c (diff) | |
download | ffmpeg-ccea588f831906084b8c8235222920e6984beb72.tar.gz |
avio: Add an option 'rw_timeout'
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>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/avio.c | 21 | ||||
-rw-r--r-- | libavformat/url.h | 1 | ||||
-rw-r--r-- | libavformat/version.h | 2 |
3 files changed, 19 insertions, 5 deletions
diff --git a/libavformat/avio.c b/libavformat/avio.c index 4da6b74165..6039990990 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -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; diff --git a/libavformat/url.h b/libavformat/url.h index 482658b7fe..408c674ddf 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -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 { diff --git a/libavformat/version.h b/libavformat/version.h index f264076f39..75d765b3e6 100644 --- a/libavformat/version.h +++ b/libavformat/version.h @@ -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, \ |