aboutsummaryrefslogtreecommitdiffstats
path: root/libavformat
diff options
context:
space:
mode:
authorAndrey Utkin <andrey.krieger.utkin@gmail.com>2012-08-27 16:31:08 +0300
committerMartin Storsjö <martin@martin.st>2016-03-24 10:33:50 +0200
commitccea588f831906084b8c8235222920e6984beb72 (patch)
tree571171710e83cbfc7f3842d4d053b5bb0023b478 /libavformat
parentd44f3e4059506a182f59218b1e967d42b01e097c (diff)
downloadffmpeg-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.c21
-rw-r--r--libavformat/url.h1
-rw-r--r--libavformat/version.h2
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, \