diff --git a/mythtv/libs/libmythtv/avfringbuffer.cpp b/mythtv/libs/libmythtv/avfringbuffer.cpp
index cdb04f7..c8bc1f1 100644
--- a/mythtv/libs/libmythtv/avfringbuffer.cpp
+++ b/mythtv/libs/libmythtv/avfringbuffer.cpp
@@ -14,9 +14,11 @@ static int AVF_Read(URLContext *h, uint8_t *buf, int buf_size)
     AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
 
     if (!avfr)
-        return 0;
+        return AVERROR(EBADF);
+
+    int ret = avfr->GetRingBuffer()->Read(buf, buf_size);
 
-    return avfr->GetRingBuffer()->Read(buf, buf_size);
+    return (ret < 0) ? AVERROR(errno) : ret;
 }
 
 static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size)
@@ -24,9 +26,11 @@ static int AVF_Write(URLContext *h, const uint8_t *buf, int buf_size)
     AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
 
     if (!avfr)
-        return 0;
+        return AVERROR(EBADF);
 
-    return avfr->GetRingBuffer()->Write(buf, buf_size);
+    int ret = avfr->GetRingBuffer()->Write(buf, buf_size);
+    
+    return (ret < 0) ? AVERROR(errno) : ret;
 }
 
 static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence)
@@ -34,7 +38,7 @@ static int64_t AVF_Seek(URLContext *h, int64_t offset, int whence)
     AVFRingBuffer *avfr = (AVFRingBuffer *)h->priv_data;
 
     if (!avfr)
-        return 0;
+        return AVERROR(EBADF);
 
     if (whence == AVSEEK_SIZE)
         return avfr->GetRingBuffer()->GetRealFileSize();
diff --git a/mythtv/libs/libmythtv/ringbuffer.cpp b/mythtv/libs/libmythtv/ringbuffer.cpp
index 5e720c2..8623137 100644
--- a/mythtv/libs/libmythtv/ringbuffer.cpp
+++ b/mythtv/libs/libmythtv/ringbuffer.cpp
@@ -1008,35 +1008,12 @@ int RingBuffer::Peek(void *buf, int count)
     return ret;
 }
 
-bool RingBuffer::WaitForReadsAllowed(void)
-{
-    MythTimer t;
-    t.start();
-
-    while (!readsallowed && !stopreads &&
-           !request_pause && !commserror && readaheadrunning)
-    {
-        generalWait.wait(&rwlock, 1000);
-        if (!readsallowed && t.elapsed() > 1000)
-        {
-            LOG(VB_GENERAL, LOG_WARNING, LOC +
-                "Taking too long to be allowed to read..");
-
-            if (t.elapsed() > 10000)
-            {
-                LOG(VB_GENERAL, LOG_ERR, LOC + "Took more than 10 seconds to "
-                                               "be allowed to read, aborting.");
-                return false;
-            }
-        }
-    }
-
-    return readsallowed;
-}
-
-bool RingBuffer::WaitForAvail(int count)
+int RingBuffer::WaitForAvail(int count, int how_long_ms)
 {
     int avail = ReadBufAvail();
+    if (avail >= count)
+        return avail;
+
     count = (ateof && avail < count) ? avail : count;
 
     if (livetvchain && setswitchtonext && avail < count)
@@ -1044,7 +1021,7 @@ bool RingBuffer::WaitForAvail(int count)
         LOG(VB_GENERAL, LOG_INFO, LOC +
             "Checking to see if there's a new livetv program to switch to..");
         livetvchain->ReloadAll();
-        return false;
+        return avail;
     }
 
     // Make sure that if the read ahead thread is sleeping and
@@ -1061,44 +1038,20 @@ bool RingBuffer::WaitForAvail(int count)
            !request_pause && !commserror && readaheadrunning)
     {
         wanttoread = count;
-        generalWait.wait(&rwlock, 250);
+        generalWait.wait(&rwlock, max(10, min(250, how_long_ms - t.elapsed())));
         avail = ReadBufAvail();
 
-        if (ateof && avail < count)
-            count = avail;
-
-        if (avail < count)
-        {
-            int elapsed = t.elapsed();
-            if (elapsed > 500 && low_buffers && avail >= fill_min)
-                count = avail;
-            else if  (((elapsed > 250) && (elapsed < 500))  ||
-                     ((elapsed >  500) && (elapsed < 750))  ||
-                     ((elapsed > 1000) && (elapsed < 1250)) ||
-                     ((elapsed > 2000) && (elapsed < 2250)) ||
-                     ((elapsed > 4000) && (elapsed < 4250)) ||
-                     ((elapsed > 8000) && (elapsed < 8250)) ||
-                     ((elapsed > 9000)))
-            {
-                LOG(VB_GENERAL, LOG_INFO, LOC + "Waited " +
-                    QString("%1").arg((elapsed / 250) * 0.25f, 3, 'f', 1) +
-                    " seconds for data \n\t\t\tto become available..." +
-                    QString(" %2 < %3") .arg(avail).arg(count));
-            }
-
-            if (elapsed > 16000)
-            {
-                LOG(VB_GENERAL, LOG_ERR, LOC + "Waited " +
-                    QString("%1").arg(elapsed/1000) +
-                    " seconds for data, aborting.");
-                return false;
-            }
-        }
+        if (ateof)
+            break;
+        if (low_buffers && avail >= fill_min)
+            break;
+        if (t.elapsed() > how_long_ms)
+            break;
     }
 
     wanttoread = 0;
 
-    return avail >= count;
+    return avail;
 }
 
 int RingBuffer::ReadDirect(void *buf, int count, bool peek)
@@ -1171,7 +1124,11 @@ int RingBuffer::ReadDirect(void *buf, int count, bool peek)
  *  \param buf   Pointer to where data will be written
  *  \param count Number of bytes to read
  *  \param peek  If true, don't increment read count
- *  \return Returns number of bytes read
+ *
+ *  \note If we return a -1, errno will be set as if the C
+ *        read function had been called on a file.
+ *
+ *  \return Returns number of bytes read, or -1 on error
  */
 int RingBuffer::ReadPriv(void *buf, int count, bool peek)
 {
@@ -1222,30 +1179,23 @@ int RingBuffer::ReadPriv(void *buf, int count, bool peek)
         rwlock.lockForRead();
     }
 
-    if (!WaitForReadsAllowed())
+    // Wait for reads allowed
+    MythTimer t; t.start();
+    const int timeout_ms = 100;
+    while ((t.elapsed() < timeout_ms) && !readsallowed && !stopreads && 
+           !request_pause && !commserror && readaheadrunning)
     {
-        LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": !WaitForReadsAllowed()");
-        rwlock.unlock();
-        stopreads = true; // this needs to be outside the lock
-        rwlock.lockForWrite();
-        wanttoread = 0;
-        rwlock.unlock();
-        return 0;
+        generalWait.wait(&rwlock, max(1, min(100, timeout_ms - t.elapsed())));
     }
-
-    if (!WaitForAvail(count))
+    if (!readsallowed)
     {
-        LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": !WaitForAvail()");
         rwlock.unlock();
-        stopreads = true; // this needs to be outside the lock
-        rwlock.lockForWrite();
-        ateof = true;
-        wanttoread = 0;
-        rwlock.unlock();
-        return 0;
+        errno = EAGAIN;
+        return -1;
     }
 
-    count = min(ReadBufAvail(), count);
+    int avail = WaitForAvail(count, max(timeout_ms - t.elapsed(), 1));
+    count = min(avail, count);
 
     if (count <= 0)
     {
@@ -1253,8 +1203,17 @@ int RingBuffer::ReadPriv(void *buf, int count, bool peek)
         // notable is an exit from the read ahead thread or
         // the end of the file stream has been reached.
         LOG(VB_FILE, LOG_NOTICE, LOC + loc_desc + ": ReadBufAvail() == 0");
-        rwlock.unlock();
-        return count;
+        if (ateof)
+        {
+            rwlock.unlock();
+            return 0;
+        }
+        else
+        {
+            rwlock.unlock();
+            errno = EAGAIN;
+            return -1;
+        }
     }
 
     if (peek)
@@ -1306,9 +1265,9 @@ int RingBuffer::Read(void *buf, int count)
         poslock.lockForWrite();
         readpos += ret;
         poslock.unlock();
+        UpdateDecoderRate(ret);
     }
 
-    UpdateDecoderRate(ret);
     return ret;
 }
 
diff --git a/mythtv/libs/libmythtv/ringbuffer.h b/mythtv/libs/libmythtv/ringbuffer.h
index 45bd956..ecbf64a 100644
--- a/mythtv/libs/libmythtv/ringbuffer.h
+++ b/mythtv/libs/libmythtv/ringbuffer.h
@@ -162,8 +162,7 @@ class MTV_PUBLIC RingBuffer : protected MThread
 
     int ReadPriv(void *buf, int count, bool peek);
     int ReadDirect(void *buf, int count, bool peek);
-    bool WaitForReadsAllowed(void);
-    bool WaitForAvail(int count);
+    int WaitForAvail(int count, int how_long_ms);
 
     int ReadBufFree(void) const;
     int ReadBufAvail(void) const;
