Mercurial > mplayer.hg
changeset 33033:1aed51b973fa
Ensure we always pass a buffer of at least sector size to the read function.
This is never an issue with streams that have actual sectors, the reads
will always return a multiple of sector size and the cache is always used
in blocks of sector size.
However the rtp protocol misuses this so it can just assume it always has
a sufficiently large buffer available and thus fails without this extra hack.
author | reimar |
---|---|
date | Sat, 26 Mar 2011 20:04:47 +0000 |
parents | dba2e7218893 |
children | e97e23af7e8f |
files | stream/cache2.c |
diffstat | 1 files changed, 18 insertions(+), 2 deletions(-) [+] |
line wrap: on
line diff
--- a/stream/cache2.c Sat Mar 26 18:37:05 2011 +0000 +++ b/stream/cache2.c Sat Mar 26 20:04:47 2011 +0000 @@ -168,6 +168,7 @@ int back,back2,newb,space,len,pos; off_t read=s->read_filepos; int read_chunk; + int wraparound_copy = 0; if(read<s->min_filepos || read>s->max_filepos){ // seek... @@ -209,8 +210,16 @@ // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos); - // reduce space if needed: - if(space>s->buffer_size-pos) space=s->buffer_size-pos; + // try to avoid wrap-around. If not possible due to sector size + // do an extra copy. + if(space>s->buffer_size-pos) { + if (s->buffer_size-pos >= s->sector_size) { + space=s->buffer_size-pos; + } else { + space = s->sector_size; + wraparound_copy = 1; + } + } // limit one-time block size read_chunk = s->stream->read_chunk; @@ -225,6 +234,13 @@ s->min_filepos=read-back; // avoid seeking-back to temp area... #endif + if (wraparound_copy) { + int to_copy; + len = stream_read_internal(s->stream, s->stream->buffer, space); + to_copy = FFMIN(len, s->buffer_size-pos); + memcpy(s->buffer + pos, s->stream->buffer, to_copy); + memcpy(s->buffer, s->stream->buffer + to_copy, len - to_copy); + } else len = stream_read_internal(s->stream, &s->buffer[pos], space); s->eof= !len;