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>
This commit is contained in:
Daniel Kucera 2017-10-17 10:29:30 +02:00 committed by Nicolas George
parent f4090940bd
commit 858db4b01f
5 changed files with 27 additions and 17 deletions

View File

@ -391,8 +391,10 @@ static inline int retry_transfer_wrapper(URLContext *h, uint8_t *buf,
} }
av_usleep(1000); av_usleep(1000);
} }
} else if (ret < 1) } else if (ret == AVERROR_EOF)
return (ret < 0 && ret != AVERROR_EOF) ? ret : len; return (len > 0) ? len : AVERROR_EOF;
else if (ret < 0)
return ret;
if (ret) { if (ret) {
fast_retries = FFMAX(fast_retries, 2); fast_retries = FFMAX(fast_retries, 2);
wait_since = 0; wait_since = 0;

View File

@ -572,13 +572,14 @@ static void fill_buffer(AVIOContext *s)
if (s->read_packet) if (s->read_packet)
len = s->read_packet(s->opaque, dst, len); len = s->read_packet(s->opaque, dst, len);
else else
len = 0; len = AVERROR_EOF;
if (len <= 0) { if (len == AVERROR_EOF) {
/* do not modify buffer if EOF reached so that a seek back can /* do not modify buffer if EOF reached so that a seek back can
be done without rereading data */ be done without rereading data */
s->eof_reached = 1; s->eof_reached = 1;
if (len < 0) } else if (len < 0) {
s->error = len; s->eof_reached = 1;
s->error= len;
} else { } else {
s->pos += len; s->pos += len;
s->buf_ptr = dst; 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 // bypass the buffer and read data directly into buf
if(s->read_packet) if(s->read_packet)
len = s->read_packet(s->opaque, buf, size); len = s->read_packet(s->opaque, buf, size);
else
if (len <= 0) { len = AVERROR_EOF;
if (len == AVERROR_EOF) {
/* do not modify buffer if EOF reached so that a seek back can /* do not modify buffer if EOF reached so that a seek back can
be done without rereading data */ be done without rereading data */
s->eof_reached = 1; s->eof_reached = 1;
if(len<0) break;
s->error= len; } else if (len < 0) {
s->eof_reached = 1;
s->error= len;
break; break;
} else { } else {
s->pos += len; s->pos += len;

View File

@ -201,7 +201,7 @@ static int cache_read(URLContext *h, unsigned char *buf, int size)
} }
r = ffurl_read(c->inner, buf, size); r = ffurl_read(c->inner, buf, size);
if (r == 0 && size>0) { if (r == AVERROR_EOF && size>0) {
c->is_true_eof = 1; c->is_true_eof = 1;
av_assert0(c->end >= c->logical_pos); av_assert0(c->end >= c->logical_pos);
} }
@ -263,7 +263,7 @@ resolve_eof:
if (whence == SEEK_SET) if (whence == SEEK_SET)
size = FFMIN(sizeof(tmp), pos - c->logical_pos); size = FFMIN(sizeof(tmp), pos - c->logical_pos);
ret = cache_read(h, tmp, size); 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); av_assert0(c->is_true_eof);
goto resolve_eof; goto resolve_eof;
} }

View File

@ -135,19 +135,20 @@ static int concat_read(URLContext *h, unsigned char *buf, int size)
while (size > 0) { while (size > 0) {
result = ffurl_read(nodes[i].uc, buf, size); result = ffurl_read(nodes[i].uc, buf, size);
if (result < 0) if (result == AVERROR_EOF) {
return total ? total : result;
if (!result) {
if (i + 1 == data->length || if (i + 1 == data->length ||
ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0) ffurl_seek(nodes[++i].uc, 0, SEEK_SET) < 0)
break; break;
result = 0;
} }
if (result < 0)
return total ? total : result;
total += result; total += result;
buf += result; buf += result;
size -= result; size -= result;
} }
data->current = i; data->current = i;
return total; return total ? total : result;
} }
static int64_t concat_seek(URLContext *h, int64_t pos, int whence) static int64_t concat_seek(URLContext *h, int64_t pos, int whence)

View File

@ -1296,8 +1296,11 @@ static int http_buf_read(URLContext *h, uint8_t *buf, int size)
"Chunked encoding data size: %"PRIu64"'\n", "Chunked encoding data size: %"PRIu64"'\n",
s->chunksize); 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; return 0;
}
else if (s->chunksize == UINT64_MAX) { else if (s->chunksize == UINT64_MAX) {
av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n", av_log(h, AV_LOG_ERROR, "Invalid chunk size %"PRIu64"\n",
s->chunksize); s->chunksize);