comparison stream/cache2.c @ 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 005b026b1231
children 62ab329812c9
comparison
equal deleted inserted replaced
33032:dba2e7218893 33033:1aed51b973fa
166 static int cache_fill(cache_vars_t *s) 166 static int cache_fill(cache_vars_t *s)
167 { 167 {
168 int back,back2,newb,space,len,pos; 168 int back,back2,newb,space,len,pos;
169 off_t read=s->read_filepos; 169 off_t read=s->read_filepos;
170 int read_chunk; 170 int read_chunk;
171 int wraparound_copy = 0;
171 172
172 if(read<s->min_filepos || read>s->max_filepos){ 173 if(read<s->min_filepos || read>s->max_filepos){
173 // seek... 174 // seek...
174 mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%"PRIX64" \n",(int64_t)read); 175 mp_msg(MSGT_CACHE,MSGL_DBG2,"Out of boundaries... seeking to 0x%"PRIX64" \n",(int64_t)read);
175 // drop cache contents only if seeking backward or too much fwd. 176 // drop cache contents only if seeking backward or too much fwd.
207 return 0; // no fill... 208 return 0; // no fill...
208 } 209 }
209 210
210 // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos); 211 // printf("### read=0x%X back=%d newb=%d space=%d pos=%d\n",read,back,newb,space,pos);
211 212
212 // reduce space if needed: 213 // try to avoid wrap-around. If not possible due to sector size
213 if(space>s->buffer_size-pos) space=s->buffer_size-pos; 214 // do an extra copy.
215 if(space>s->buffer_size-pos) {
216 if (s->buffer_size-pos >= s->sector_size) {
217 space=s->buffer_size-pos;
218 } else {
219 space = s->sector_size;
220 wraparound_copy = 1;
221 }
222 }
214 223
215 // limit one-time block size 224 // limit one-time block size
216 read_chunk = s->stream->read_chunk; 225 read_chunk = s->stream->read_chunk;
217 if (!read_chunk) read_chunk = 4*s->sector_size; 226 if (!read_chunk) read_chunk = 4*s->sector_size;
218 space = FFMIN(space, read_chunk); 227 space = FFMIN(space, read_chunk);
223 if(s->min_filepos<(read-back2)) s->min_filepos=read-back2; 232 if(s->min_filepos<(read-back2)) s->min_filepos=read-back2;
224 #else 233 #else
225 s->min_filepos=read-back; // avoid seeking-back to temp area... 234 s->min_filepos=read-back; // avoid seeking-back to temp area...
226 #endif 235 #endif
227 236
237 if (wraparound_copy) {
238 int to_copy;
239 len = stream_read_internal(s->stream, s->stream->buffer, space);
240 to_copy = FFMIN(len, s->buffer_size-pos);
241 memcpy(s->buffer + pos, s->stream->buffer, to_copy);
242 memcpy(s->buffer, s->stream->buffer + to_copy, len - to_copy);
243 } else
228 len = stream_read_internal(s->stream, &s->buffer[pos], space); 244 len = stream_read_internal(s->stream, &s->buffer[pos], space);
229 s->eof= !len; 245 s->eof= !len;
230 246
231 s->max_filepos+=len; 247 s->max_filepos+=len;
232 if(pos+len>=s->buffer_size){ 248 if(pos+len>=s->buffer_size){