Commit ccea588f authored by Andrey Utkin's avatar Andrey Utkin Committed by Martin Storsjö

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: 's avatarMartin Storsjö <martin@martin.st>
parent d44f3e40
...@@ -17,6 +17,14 @@ particular protocol using the option ...@@ -17,6 +17,14 @@ particular protocol using the option
The option "-protocols" of the av* tools will display the list of The option "-protocols" of the av* tools will display the list of
supported protocols. 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. A description of the currently available protocols follows.
@section concat @section concat
......
...@@ -49,7 +49,10 @@ static void *urlcontext_child_next(void *obj, void *prev) ...@@ -49,7 +49,10 @@ static void *urlcontext_child_next(void *obj, void *prev)
return NULL; 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 = { const AVClass ffurl_context_class = {
.class_name = "URLContext", .class_name = "URLContext",
.item_name = urlcontext_to_name, .item_name = urlcontext_to_name,
...@@ -199,6 +202,7 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, ...@@ -199,6 +202,7 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
{ {
int ret, len; int ret, len;
int fast_retries = 5; int fast_retries = 5;
int64_t wait_since = 0;
len = 0; len = 0;
while (len < size_min) { while (len < size_min) {
...@@ -209,14 +213,23 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf, ...@@ -209,14 +213,23 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
return ret; return ret;
if (ret == AVERROR(EAGAIN)) { if (ret == AVERROR(EAGAIN)) {
ret = 0; ret = 0;
if (fast_retries) if (fast_retries) {
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); av_usleep(1000);
}
} else if (ret < 1) } else if (ret < 1)
return (ret < 0 && ret != AVERROR_EOF) ? ret : len; return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
if (ret) if (ret) {
fast_retries = FFMAX(fast_retries, 2); fast_retries = FFMAX(fast_retries, 2);
wait_since = 0;
}
len += ret; len += ret;
if (ff_check_interrupt(&h->interrupt_callback)) if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT; return AVERROR_EXIT;
......
...@@ -49,6 +49,7 @@ typedef struct URLContext { ...@@ -49,6 +49,7 @@ typedef struct URLContext {
int is_streamed; /**< true if streamed (no seek possible), default = false */ int is_streamed; /**< true if streamed (no seek possible), default = false */
int is_connected; int is_connected;
AVIOInterruptCB interrupt_callback; AVIOInterruptCB interrupt_callback;
int64_t rw_timeout; /**< maximum time to wait for (network) read/write operation completion, in microseconds */
} URLContext; } URLContext;
typedef struct URLProtocol { typedef struct URLProtocol {
......
...@@ -31,7 +31,7 @@ ...@@ -31,7 +31,7 @@
#define LIBAVFORMAT_VERSION_MAJOR 57 #define LIBAVFORMAT_VERSION_MAJOR 57
#define LIBAVFORMAT_VERSION_MINOR 5 #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, \ #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
LIBAVFORMAT_VERSION_MINOR, \ LIBAVFORMAT_VERSION_MINOR, \
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment