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>tags/n3.1
| @@ -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) | |||||
| 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, | |||||
| { | { | ||||
| 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, | |||||
| 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 { | |||||
| 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 @@ | |||||
| #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, \ | ||||