Am 30.12.2017 um 18:07 schrieb wm4:
It makes no sense to return an error after the first reconnect, and then
somehow resume the next time it's called.

Also make the wait reasonably interruptible. Since there is no mechanism
for this in the API, polling is the best we can do. (Some effort could
be put into making the wait more accurate, since the av_usleep() will
not wait exactly 1000 microseconds, and the error will add up.)

(The original code would work if it returned AVERROR(EAGAIN) or so,
which would make retry_transfer_wrapper() repeat the read call. But I
think having an explicit loop for this is better anyway.)
---
  libavformat/http.c | 22 +++++++++++++---------
  1 file changed, 13 insertions(+), 9 deletions(-)

diff --git a/libavformat/http.c b/libavformat/http.c
index a376f1a488..2957648d61 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1443,25 +1443,29 @@ static int http_read_stream(URLContext *h, uint8_t 
*buf, int size)
          return http_buf_read_compressed(h, buf, size);
  #endif /* CONFIG_ZLIB */
      read_ret = http_buf_read(h, buf, size);
-    if (   (read_ret  < 0 && s->reconnect        && (!h->is_streamed || s->reconnect_streamed) && 
s->filesize > 0 && s->off < s->filesize)
+    while (   (read_ret  < 0 && s->reconnect        && (!h->is_streamed || s->reconnect_streamed) && 
s->filesize > 0 && s->off < s->filesize)
nit: could just get rid of the extra whitespace here and it will be perfectly aligned with the next line.

          || (read_ret == 0 && s->reconnect_at_eof && (!h->is_streamed || 
s->reconnect_streamed))) {
+        unsigned int wait = 0;
          uint64_t target = h->is_streamed ? 0 : s->off;
if (s->reconnect_delay > s->reconnect_delay_max)
              return AVERROR(EIO);
av_log(h, AV_LOG_INFO, "Will reconnect at %"PRIu64" error=%s.\n", s->off, av_err2str(read_ret));
-        av_usleep(1000U*1000*s->reconnect_delay);
+        for (wait = 0; wait < 1000U*s->reconnect_delay; wait++) {
+            if (ff_check_interrupt(&h->interrupt_callback))
+                return AVERROR(EIO);
+            av_usleep(1000);
+        }
          s->reconnect_delay = 1 + 2*s->reconnect_delay;
          seek_ret = http_seek_internal(h, target, SEEK_SET, 1);
-        if (seek_ret != target) {
+        if (seek_ret >= 0 && seek_ret != target) {
              av_log(h, AV_LOG_ERROR, "Failed to reconnect at %"PRIu64".\n", 
target);
-            return read_ret;
-        }
-
-        read_ret = http_buf_read(h, buf, size);
-    } else
-        s->reconnect_delay = 0;
+            return AVERROR(EIO);
+        } else
+            read_ret = http_buf_read(h, buf, size);
+    }
+    s->reconnect_delay = 0;
return read_ret;
  }


looks reasonable to me, but it's not my code and I don't have any experience with it.

Attachment: smime.p7s
Description: S/MIME Cryptographic Signature

_______________________________________________
ffmpeg-devel mailing list
ffmpeg-devel@ffmpeg.org
http://ffmpeg.org/mailman/listinfo/ffmpeg-devel

Reply via email to