summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Kucera <daniel.kucera@gmail.com>2017-10-17 10:29:30 +0200
committerNicolas George <george@nsup.org>2017-10-19 22:07:21 +0200
commit858db4b01fa2b55ee55056c033054ca54ac9b0fd (patch)
tree5a29252c4545b4ff80bb0beead0628812d0b73b9
parentf4090940bd3024e69d236257d327f11d1e496229 (diff)
libavformat: not treat 0 as EOF
transfer_func variable passed to retry_transfer_wrapper are h->prot->url_read and h->prot->url_write functions. These need to return EOF or other error properly. In case of returning >= 0, url_read/url_write is retried until error is returned. Signed-off-by: Daniel Kucera <daniel.kucera@gmail.com>
-rw-r--r--libavformat/avio.c6
-rw-r--r--libavformat/aviobuf.c20
-rw-r--r--libavformat/cache.c4
-rw-r--r--libavformat/concat.c9
-rw-r--r--libavformat/http.c5
5 files changed, 27 insertions, 17 deletions
diff --git a/libavformat/avio.c b/libavformat/avio.c
index 64248e098b..4718753b7b 100644
--- a/libavformat/avio.c
+++ b/libavformat/avio.c
@@ -391,8 +391,10 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
}
av_usleep(1000);
}
- } else if (ret < 1)
- return (ret < 0 && ret != AVERROR_EOF) ? ret : len;
+ } else if (ret == AVERROR_EOF)
+ return (len > 0) ? len : AVERROR_EOF;
+ else if (ret < 0)
+ return ret;
if (ret) {
fast_retries = FFMAX(fast_retries, 2);
wait_since = 0;
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 636cb46161..0d4eb051e1 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -572,13 +572,14 @@ static void fill_buffer(AVIOContext *s)
if (s->read_packet)
len = s->read_packet(s->opaque, dst, len);
else
- len = 0;
- if (len <= 0) {
+ len = AVERROR_EOF;
+ if (len == AVERROR_EOF) {
/* do not modify buffer if EOF reached so that a seek back can
be done without rereading data */
s->eof_reached = 1;
- if (len < 0)
- s->error = len;
+ } else if (len < 0) {
+ s->eof_reached = 1;
+ s->error= len;
} else {
s->pos += len;
s->buf_ptr = dst;
@@ -646,13 +647,16 @@ int avio_read(AVIOContext *s, unsigned char *buf, int size)
// bypass the buffer and read data directly into buf
if(s->read_packet)
len = s->read_packet(s->opaque, buf, size);
-
- if (len <= 0) {
+ else
+ len = AVERROR_EOF;
+ if (len == AVERROR_EOF) {
/* do not modify buffer if EOF reached so that a seek back can
be done without rereading data */
s->eof_reached = 1;
- if(len<0)
- s->error= len;
+ break;
+ } else if (len < 0) {
+ s->eof_reached = 1;
+ s->error= len;
break;
} else {
s->pos += len;
diff --git a/libavformat/cache.c b/libavformat/cache.c
index 6aabca2e78..66bbbf54c9 100644
--- a/libavformat/cache.c
+++ b/libavformat/cache.c
@@ -201,7 +201,7 @@ static int cache_read(URLContext *h, unsigned char *buf, int size)
}
r = ffurl_read(c->inner, buf, size);
- if (r == 0 && size>0) {
+ if (r == AVERROR_EOF && size>0) {
c->is_true_eof = 1;
av_assert0(c->end >= c->logical_pos);
}
@@ -263,7 +263,7 @@ resolve_eof:
if (whence == SEEK_SET)
size = FFMIN(sizeof(tmp), pos - c->logical_pos);
ret = cache_read(h, tmp, size);
- if (ret == 0 && whence == SEEK_END) {
+ if (ret == AVERROR_EOF && whence == SEEK_END) {
av_assert0(c->is_true_eof);
goto resolve_eof;
}
diff --git a/libavformat/concat.c b/libavformat/concat.c
index 46b520fe80..19c83c309a 100644
--- a/libavformat/concat.c
+++ b/libavformat/concat.c
@@ -135,19 +135,20 @@ static int concat_read(URLContext *h, unsigned char *buf, int size)
while (size > 0) {
result = ffurl_read(nodes[i].uc, buf, size);
- if (result < 0)
- return total ? total : result;
- if (!result) {
+ if (result == AVERROR_EOF) {
if (i + 1 == data->length ||
ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0)
break;
+ result = 0;
}
+ if (result < 0)
+ return total ? total : result;
total += result;
buf += result;
size -= result;
}
data->current = i;
- return total;
+ return total ? total : result;
}
static int64_t concat_seek(URLContext *h, int64_t pos, int whence)
diff --git a/libavformat/http.c b/libavformat/http.c
index 668cd51986..bd9148f45d 100644
--- a/libavformat/http.c
+++ b/libavformat/http.c
@@ -1296,8 +1296,11 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
"Chunked encoding data size: %"PRIu64"'\n",
s->chunksize);
- if (!s->chunksize)
+ if (!s->chunksize) {
+ av_log(h, AV_LOG_DEBUG, "Last chunk received, closing conn\n");
+ ffurl_closep(&s->hd);
return 0;
+ }
else if (s->chunksize == UINT64_MAX) {
av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
s->chunksize);