mirror of https://git.ffmpeg.org/ffmpeg.git
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:
parent
f4090940bd
commit
858db4b01f
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue