Index: libs/libmythtv/nuppeldecoder.cpp
===================================================================
--- libs/libmythtv/nuppeldecoder.cpp	(revision 13188)
+++ libs/libmythtv/nuppeldecoder.cpp	(working copy)
@@ -547,7 +547,8 @@
     if (usingextradata && extradata.video_fourcc == MKTAG('D', 'I', 'V', 'X'))
         setreadahead = true;
 
-    ringBuffer->UpdateRawBitrate(0);
+    bitrate = 0;
+    ringBuffer->UpdateRawBitrate(GetRawBitrate());
 
     videosizetotal = 0;
     videoframesread = 0;
@@ -1099,10 +1100,11 @@
                 {
                     videosizetotal /= videoframesread;
 
-                    float bps = videosizetotal * 8.0 / 1024 * video_frame_rate;
-                    bps = bps * 3 / 2;
+                    float bps = (videosizetotal * 8.0f / 1024.0f *
+                                 video_frame_rate);
+                    bitrate = (uint) (bps * 1.5f);
 
-                    ringBuffer->UpdateRawBitrate((uint) bps);
+                    ringBuffer->UpdateRawBitrate(GetRawBitrate());
                     setreadahead = true;
                 }
             }
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 13188)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -2844,6 +2844,9 @@
         return;
     }
 
+    // the bitrate is reset by ringBuffer->OpenFile()...
+    ringBuffer->UpdateRawBitrate(GetDecoder()->GetRawBitrate());
+
     ringBuffer->Unpause();
 
     if (discontinuity || newtype)
@@ -2949,6 +2952,9 @@
         return;
     }
 
+    // the bitrate is reset by ringBuffer->OpenFile()...
+    ringBuffer->UpdateRawBitrate(GetDecoder()->GetRawBitrate());
+
     ringBuffer->Unpause();
     ringBuffer->IgnoreLiveEOF(false);
 
@@ -3464,6 +3470,8 @@
 
     timecode += tc_wrap[tc_type];
 
+#define DOTCWRAP 0
+#if DOTCWRAP
     // wrapped
     if (timecode < tc_lastval[tc_type] - 10000)
     {
@@ -3500,6 +3508,7 @@
             tc_avcheck_framecounter = 0;
         }
     }
+#endif
 }
 
 /** \fn NuppelVideoPlayer::AddAudioData(char*,int,long long)
Index: libs/libmythtv/avformatdecoder.cpp
===================================================================
--- libs/libmythtv/avformatdecoder.cpp	(revision 13188)
+++ libs/libmythtv/avformatdecoder.cpp	(working copy)
@@ -266,7 +266,6 @@
       ic(NULL),
       frame_decoded(0),             decoded_video_frame(NULL),
       directrendering(false),       drawband(false),
-      bitrate(0),
       gopset(false),                seen_gop(false),
       seq_count(0),                 firstgoppos(0),
       prevgoppos(0),                gotvideo(false),
Index: libs/libmythtv/decoderbase.h
===================================================================
--- libs/libmythtv/decoderbase.h	(revision 13188)
+++ libs/libmythtv/decoderbase.h	(working copy)
@@ -79,6 +79,8 @@
 
     virtual QString GetEncodingType(void) const = 0;
     virtual double  GetFPS(void) const { return fps; }
+    /// Returns the estimated bitrate if the video were played at normal speed.
+    uint GetRawBitrate(void) const { return bitrate; }
 
     virtual void UpdateFramesPlayed(void);
     long long GetFramesRead(void) const { return framesRead; };
@@ -163,6 +165,7 @@
     int current_height;
     float current_aspect;
     double fps;
+    uint bitrate;
 
     long long framesPlayed;
     long long framesRead;
Index: libs/libmythtv/RingBuffer.cpp
===================================================================
--- libs/libmythtv/RingBuffer.cpp	(revision 13188)
+++ libs/libmythtv/RingBuffer.cpp	(working copy)
@@ -7,6 +7,7 @@
 // POSIX C headers
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <sys/time.h>
 #include <unistd.h>
 #include <fcntl.h>
 #include <pthread.h>
@@ -39,8 +40,10 @@
 #define O_LARGEFILE 0
 #endif
 
-const uint RingBuffer::kBufferSize = 10 * 256 * 1024;
+const uint RingBuffer::kBufferSize = 3 * 1024 * 1024;
 
+#define CHUNK 32768 /* readblocksize increments */
+
 #define PNG_MIN_SIZE   20 /* header plus one empty chunk */
 #define NUV_MIN_SIZE  204 /* header size? */
 #define MPEG_MIN_SIZE 376 /* 2 TS packets */
@@ -92,8 +95,8 @@
       internalreadpos(0),       ateof(false),
       readsallowed(false),      wantseek(false), setswitchtonext(false),
       rawbitrate(4000),         playspeed(1.0f),
-      fill_threshold(-1),       fill_min(-1),
-      readblocksize(128000),    wanttoread(0),
+      fill_threshold(65536),    fill_min(-1),
+      readblocksize(CHUNK),     wanttoread(0),
       numfailures(0),           commserror(false),
       dvdPriv(NULL),            oldfile(false),
       livetvchain(NULL),        ignoreliveeof(false),
@@ -534,48 +537,51 @@
  */
 void RingBuffer::CalcReadAheadThresh(void)
 {
-    const uint KB32  =  32*1024;
-    const uint KB64  =  64*1024;
-    const uint KB128 = 128*1024;
-    const uint KB256 = 256*1024;
-    const uint KB512 = 512*1024;
     uint estbitrate;
 
-    wantseek = true;
     pthread_rwlock_wrlock(&rwlock);
-
-    estbitrate     = (uint) max(abs(rawbitrate * playspeed), 0.5f * rawbitrate);
-    estbitrate     = min(rawbitrate * 3, estbitrate);
     wantseek       = false;
     readsallowed   = false;
+    readblocksize  = CHUNK;
+
+    // loop without sleeping if the buffered data is less than this
+    fill_threshold = CHUNK * 2;
     fill_min       = 1;
-    readblocksize  = (estbitrate > 2500)  ? KB64  : KB32;
-    readblocksize  = (estbitrate > 5000)  ? KB128 : readblocksize;
-    readblocksize  = (estbitrate > 9000)  ? KB256 : readblocksize;
-    readblocksize  = (estbitrate > 18000) ? KB512 : readblocksize;
 
-    uint  secs_thr = 300; // seconds of buffering desired
-    float secs_min = 0.1; // minumum seconds of buffering before allowing read
+#ifdef USING_FRONTEND
+    if (dvdPriv)
+    {
+        const uint KB32  =  32*1024;
+        const uint KB64  =  64*1024;
+        const uint KB128 = 128*1024;
+        const uint KB256 = 256*1024;
+        const uint KB512 = 512*1024;
 
-    // set basic fill_threshold based on bitrate
-    fill_threshold = (estbitrate * secs_thr) >> 3; // >>3 => bits -> bytes
-    // extra buffering for remote files
-    fill_threshold = fill_threshold + ((remotefile) ? KB256 : 0);
-    // make the fill_threshold at least one block
-    fill_threshold = max(readblocksize, fill_threshold);
+        estbitrate     = (uint) max(abs(rawbitrate * playspeed),
+                                    0.5f * rawbitrate);
+        estbitrate     = min(rawbitrate * 3, estbitrate);
+        readblocksize  = (estbitrate > 2500)  ? KB64  : KB32;
+        readblocksize  = (estbitrate > 5000)  ? KB128 : readblocksize;
+        readblocksize  = (estbitrate > 9000)  ? KB256 : readblocksize;
+        readblocksize  = (estbitrate > 18000) ? KB512 : readblocksize;
 
-    // set the minimum buffering before allowing ffmpeg read
-    fill_min        = (uint) ((estbitrate * secs_min) * 0.125f);
-    // make this a multiple of ffmpeg block size..
-    fill_min        = ((fill_min / KB32) + 1) * KB32;
+        // minumum seconds of buffering before allowing read
+        float secs_min = 0.1;
 
+        // set the minimum buffering before allowing ffmpeg read
+        fill_min        = (uint) ((estbitrate * secs_min) * 0.125f);
+        // make this a multiple of ffmpeg block size..
+        fill_min        = ((fill_min / KB32) + 1) * KB32;
+    }
+#endif // USING_FRONTEND    
+
+    pthread_rwlock_unlock(&rwlock);
+
     VERBOSE(VB_PLAYBACK, LOC +
             QString("CalcReadAheadThresh(%1 KB)\n\t\t\t -> "
                     "threshhold(%2 KB) min read(%3 KB) blk size(%4 KB)")
             .arg(estbitrate).arg(fill_threshold/1024)
             .arg(fill_min/1024).arg(readblocksize/1024));
-
-    pthread_rwlock_unlock(&rwlock);
 }
 
 /** \fn RingBuffer::ReadBufFree(void) const
@@ -611,6 +617,7 @@
 void RingBuffer::ResetReadAhead(long long newinternal)
 {
     readAheadLock.lock();
+    readblocksize = CHUNK;
     rbrpos = 0;
     rbwpos = 0;
     internalreadpos = newinternal;
@@ -722,9 +729,15 @@
     int used = 0;
     int loops = 0;
 
+    struct timeval lastread, now;
+    gettimeofday(&lastread, NULL);
+    const int KB640 = 640*1024;
+    int readtimeavg = 300;
+    int readinterval;
+
     pausereadthread = false;
 
-    readAheadBuffer = new char[kBufferSize + 256000];
+    readAheadBuffer = new char[kBufferSize + KB640];
 
     ResetReadAhead(0);
     totfree = ReadBufFree();
@@ -768,6 +781,31 @@
             // limit the read size
             totfree = readblocksize;
 
+            // adapt blocksize
+            gettimeofday(&now, NULL);
+            readinterval = (now.tv_sec  - lastread.tv_sec ) * 1000 +
+                           (now.tv_usec - lastread.tv_usec) / 1000;
+
+            readtimeavg = (readtimeavg * 9 + readinterval) / 10;
+
+            if (readtimeavg < 200 && readblocksize < KB640)
+            {
+                readblocksize += CHUNK;
+                VERBOSE(VB_PLAYBACK,
+                    QString("Avg read interval was %1 msec. %2K block size")
+                            .arg(readtimeavg).arg(readblocksize/1024));
+                readtimeavg = 300;
+            }
+            else if (readtimeavg > 400 && readblocksize > CHUNK)
+            {
+                readblocksize -= CHUNK;
+                VERBOSE(VB_PLAYBACK,
+                    QString("Avg read interval was %1 msec. %2K block size")
+                            .arg(readtimeavg).arg(readblocksize/1024));
+                readtimeavg = 300;
+            }
+            lastread = now;
+
             if (rbwpos + totfree > kBufferSize)
                 totfree = kBufferSize - rbwpos;
 
Index: libs/libmythtv/decoderbase.cpp
===================================================================
--- libs/libmythtv/decoderbase.cpp	(revision 13188)
+++ libs/libmythtv/decoderbase.cpp	(working copy)
@@ -23,6 +23,7 @@
 
       current_width(640), current_height(480),
       current_aspect(1.33333), fps(29.97),
+      bitrate(4000),
 
       framesPlayed(0), framesRead(0), lastKey(0), keyframedist(-1),
       indexOffset(0),
Index: libs/libmythtv/avformatdecoder.h
===================================================================
--- libs/libmythtv/avformatdecoder.h	(revision 13188)
+++ libs/libmythtv/avformatdecoder.h	(working copy)
@@ -204,8 +204,6 @@
     bool directrendering;
     bool drawband;
 
-    int bitrate;
-
     bool gopset;
     /// A flag to indicate that we've seen a GOP frame.  Used in junction with seq_count.
     bool seen_gop;
Index: libs/libmythtv/ivtvdecoder.cpp
===================================================================
--- libs/libmythtv/ivtvdecoder.cpp	(revision 13188)
+++ libs/libmythtv/ivtvdecoder.cpp	(working copy)
@@ -49,6 +49,7 @@
 {
     lastResetTime.start();
     fps = 29.97f;
+    bitrate = 8000;
     lastKey = 0;
 }
 
@@ -277,7 +278,7 @@
 
     fps = (ntsc) ? 29.97f : 25.0f; // save for later length calculations
 
-    ringBuffer->UpdateRawBitrate(8000);
+    ringBuffer->UpdateRawBitrate(GetRawBitrate());
 
     if (m_playbackinfo || livetv || watchingrecording)
     {
