Index: RingBuffer.cpp =================================================================== --- RingBuffer.cpp (revision 25861) +++ RingBuffer.cpp (working copy) @@ -44,7 +44,8 @@ #define O_BINARY 0 #endif -const uint RingBuffer::kBufferSize = 3 * 1024 * 1024; +#define OLD_DATA_LIMIT (2 * 1024 * 1024) +const uint RingBuffer::kBufferSize = 6 * 1024 * 1024; #define CHUNK 32768 /* readblocksize increments */ @@ -121,7 +122,7 @@ startreadahead(readahead),readAheadBuffer(NULL), readaheadrunning(false), readaheadpaused(false), pausereadthread(false), - rbrpos(0), rbwpos(0), + rbrpos(0), rbwpos(0), rbopos(0), internalreadpos(0), ateof(false), readsallowed(false), wantseek(false), setswitchtonext(false), streamOnly(false), @@ -816,7 +817,7 @@ int RingBuffer::ReadBufFree(void) const { QMutexLocker locker(&readAheadLock); - return ((rbwpos >= rbrpos) ? rbrpos + kBufferSize : rbrpos) - rbwpos - 1; + return ((rbwpos >= rbrpos) ? rbrpos + kBufferSize : rbrpos) - rbwpos - 1 - OLD_DATA_LIMIT; } /** \fn RingBuffer::ReadBufAvail(void) const @@ -844,6 +845,7 @@ { readAheadLock.lock(); readblocksize = CHUNK; + rbopos = 0; rbrpos = 0; rbwpos = 0; internalreadpos = newinternal; @@ -1034,6 +1036,45 @@ if (internalreadpos == 0) totfree = fill_min; + readAheadLock.lock(); + if (totfree > 0) // always true in this case + { + int relrpos = 0; + int relwpos = 0; + int relopos = 0; + + // This: ----O------R-----W---- or -----R----W---O----- to ----O----------------R----W---- + // From This: ----O------R----W--- + // to This: ------------------------O------R----W--- + // OR This: : -----------R----W-O- + // to This: ------------------O------------R----W--- + if (rbwpos > rbrpos) + { + relrpos = rbrpos + kBufferSize; + relwpos = rbwpos + kBufferSize; + if (rbopos < rbrpos) + relopos = rbopos + kBufferSize; + else + relopos = rbopos; + } + // From This: ----W------O----R--- + // to This: -----------O----R-------W--------------- + else if (rbwpos < rbrpos) + { + relrpos = rbrpos; + relwpos = rbwpos + kBufferSize; + relopos = rbopos; + } + + if ((rbopos != rbrpos) && (rbopos != rbrpos) && (relwpos + totfree) > (relopos + kBufferSize)) + { + int oldData = (rbrpos > rbopos) ? (rbrpos - rbopos) : rbrpos + kBufferSize - rbopos; + if (oldData > OLD_DATA_LIMIT) + rbopos = (rbrpos + kBufferSize - OLD_DATA_LIMIT) % kBufferSize; + } + } + readAheadLock.unlock(); + if (remotefile) { if (livetvchain && livetvchain->HasNext()) @@ -1136,6 +1177,7 @@ delete [] readAheadBuffer; readAheadBuffer = NULL; + rbopos = 0; rbrpos = 0; rbwpos = 0; } @@ -1465,6 +1507,8 @@ */ long long RingBuffer::Seek(long long pos, int whence) { + static char tmpSeekBuf[1024*1024]; + if (writemode) return WriterSeek(pos, whence); @@ -1480,6 +1524,48 @@ return readpos; } + if ((whence == SEEK_SET) || (whence == SEEK_CUR)) + { + int newpos = pos; + if (whence == SEEK_CUR) + newpos = readpos + pos; + + if (newpos < readpos) + { + int oldData = (rbrpos > rbopos) ? (rbrpos - rbopos) : rbrpos + kBufferSize - rbopos; + if ((readpos - newpos) <= oldData) + { + rbrpos = ((rbrpos + kBufferSize) - (readpos - newpos)) % kBufferSize; + readpos -= (readpos - newpos); + rwlock.unlock(); + return readpos; + } + } + else + { + int newData = (rbwpos > rbrpos) ? (rbwpos - rbrpos) : rbwpos + kBufferSize - rbrpos; + if ((newpos - readpos) <= newData) + { + rbrpos = ((rbrpos + kBufferSize) + (newpos - readpos)) % kBufferSize; + readpos += (newpos - readpos); + rwlock.unlock(); + return readpos; + } + } + + // If the desired position is less than a meg away, just read the data + // rather than seeking to it. + if ((newpos > readpos) && ((newpos - readpos) < (1024*1024))) + { + rwlock.unlock(); + int ret = ReadFromBuf(tmpSeekBuf, newpos - readpos); + rwlock.lockForWrite(); + readpos += ret; + rwlock.unlock(); + return readpos; + } + } + errno = 0; // clear errno, in case of remotefile error long long ret = -1; Index: RingBuffer.h =================================================================== --- RingBuffer.h (revision 25861) +++ RingBuffer.h (working copy) @@ -155,6 +155,7 @@ bool readaheadrunning; // not protected by a lock HR bool readaheadpaused; // not protected by a lock HR bool pausereadthread; // not protected by a lock HR + int rbopos; // not protected by a lock HR int rbrpos; // not protected by a lock HR int rbwpos; // not protected by a lock HR long long internalreadpos; // not protected by a lock HR