# HG changeset patch # User reimar # Date 1301169887 0 # Node ID 1aed51b973fa3b3b919c32a7e870e69834aa86f2 # Parent dba2e72188937aaf0185d8b5cb1864ae0c698ac9 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. diff -r dba2e7218893 -r 1aed51b973fa stream/cache2.c --- 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(readmin_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;