From a37b71dc329b4cfc828db9c166c94d1221f2d46c Mon Sep 17 00:00:00 2001 From: reimar Date: Sat, 26 Mar 2011 20:04:47 +0000 Subject: cache: call stream read with at least sector size space 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, as 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. git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@33120 b3059339-0415-0410-9bf9-f77b7e298cf2 --- stream/cache2.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/stream/cache2.c b/stream/cache2.c index 9e4bea35b4..e930d72255 100644 --- a/stream/cache2.c +++ b/stream/cache2.c @@ -167,6 +167,7 @@ static int cache_fill(cache_vars_t *s) int back,back2,newb,space,len,pos; off_t read=s->read_filepos; int read_chunk; + int wraparound_copy = 0; if(readmin_filepos || read>s->max_filepos){ // seek... @@ -208,8 +209,16 @@ static int cache_fill(cache_vars_t *s) // 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; @@ -224,6 +233,13 @@ static int cache_fill(cache_vars_t *s) 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; -- cgit v1.2.3