summaryrefslogtreecommitdiff
path: root/libavformat/aviobuf.c
diff options
context:
space:
mode:
authorMartin Storsjö <martin@martin.st>2010-07-24 09:04:44 +0000
committerMartin Storsjö <martin@martin.st>2010-07-24 09:04:44 +0000
commit496c645d3b3bb5ded7f5ce918ca21d3acac6b8df (patch)
tree6a7d7efa6a484e9f90e7fb0ac1a2e18b7134baa8 /libavformat/aviobuf.c
parent8dd25c52cbf57d4a28885abcc950c27a24606036 (diff)
Never shrink the ByteIOContext buffer in ff_rewind_with_probe_data
If there is little unread data in the ByteIOContext buffer, this may lead to reducing the size of the ByteIOContext buffer to little more the probe data size. This can lead to suboptimal aviobuf behaviour, e.g. making some demuxers fail to do short seeks backwards (if the input isn't seekable). Originally committed as revision 24478 to svn://svn.ffmpeg.org/ffmpeg/trunk
Diffstat (limited to 'libavformat/aviobuf.c')
-rw-r--r--libavformat/aviobuf.c11
1 files changed, 7 insertions, 4 deletions
diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c
index 5841966c9b..941691adb6 100644
--- a/libavformat/aviobuf.c
+++ b/libavformat/aviobuf.c
@@ -667,7 +667,7 @@ int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size
{
int64_t buffer_start;
int buffer_size;
- int overlap, new_size;
+ int overlap, new_size, alloc_size;
if (s->write_flag)
return AVERROR(EINVAL);
@@ -681,17 +681,20 @@ int ff_rewind_with_probe_data(ByteIOContext *s, unsigned char *buf, int buf_size
overlap = buf_size - buffer_start;
new_size = buf_size + buffer_size - overlap;
- if (new_size > buf_size) {
- if (!(buf = av_realloc(buf, new_size)))
+ alloc_size = FFMAX(s->buffer_size, new_size);
+ if (alloc_size > buf_size)
+ if (!(buf = av_realloc(buf, alloc_size)))
return AVERROR(ENOMEM);
+ if (new_size > buf_size) {
memcpy(buf + buf_size, s->buffer + overlap, buffer_size - overlap);
buf_size = new_size;
}
av_free(s->buffer);
s->buf_ptr = s->buffer = buf;
- s->pos = s->buffer_size = buf_size;
+ s->buffer_size = alloc_size;
+ s->pos = buf_size;
s->buf_end = s->buf_ptr + buf_size;
s->eof_reached = 0;
s->must_flush = 0;