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);
}
} 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;

View File

@ -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;

View File

@ -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;
}

View File

@ -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)

View File

@ -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);