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);
|
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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in New Issue