[mythtv] Small code improvement.

michael at optusnet.com.au michael at optusnet.com.au
Sat May 10 15:59:13 EDT 2003


In trying to work out why LiveTV was skipping occasionally
I stumbled across a very odd piece of code.

In RingBuffer.cpp, there's code to read from a remotefile.
It _looks_ like it was supposed to maintain a window of
requests ahead of the reads. Unfortunately, it's doesn't
achieve that purpose.

The patch below re-writes it to actually do something sane.
It maintains a 'window' of about 1.5megabytes of requests
in flight at any one time, sending new requests as reads
consume 'in-flight' data.

It adds a new private variable to the RingBuffer object
called 'requested' which is the count of data that's
been requested but not consumed. It's reset to zero
whenever a seek is done, the file is reset, or re-opened.



I've also made worse something that annoys me a lot.

Mythtv seems to be full of 'magic numbers' that aren't in
configuration files. There's a magic number setting the
videobuffer at 20megs for high res, and 12 meg for low res.
There's another one setting the ring buffer size at 2 meg.
There's yet another one setting the size of the audio
buffer for playback. And yet another one setting the
number of buffers available in playback. And another
one setting the number of 'prebuffer' frames.

Is there an intention to turn these into variable and move
into a configuration file somewhere!?

(Given that I had 512Meg of ram on my media box, it makes
a lot of sense to set some of these buffers much higher,
but currently the only way to do that is stumble across
the setting when reading the source code, and re-compile).

Michael.


diff -ur mythtv-0.8/libs/libmythtv/RingBuffer.cpp mythtv-local/libs/libmythtv/RingBuffer.cpp
--- mythtv-0.8/libs/libmythtv/RingBuffer.cpp	2003-03-08 11:22:04.000000000 +1100
+++ mythtv-local/libs/libmythtv/RingBuffer.cpp	2003-05-09 14:51:05.000000000 +1000
@@ -17,7 +17,8 @@
 #include "remotefile.h"
 #include "remoteencoder.h"
 
-#define TFW_BUF_SIZE (2*1024*1024)
+#define TFW_BUF_SIZE (2*1024*1024)
+
 
 class ThreadedFileWriter
 {
@@ -252,6 +253,7 @@
     totalwritepos = writepos = 0;
     totalreadpos = readpos = 0;
     smudgeamount = 0;
+    requested = 0;
 
     stopreads = false;
     dumpfw = NULL;
@@ -295,6 +297,7 @@
 
     totalwritepos = writepos = 0;
     totalreadpos = readpos = 0;
+    requested = 0;
 
     wrapcount = 0;
     smudgeamount = smudge;
@@ -312,6 +315,7 @@
     if (remotefile)
     {
         delete remotefile;
+	requested = 0;
     }
     if (tfw)
     {
@@ -331,8 +335,10 @@
 
 void RingBuffer::Start(void)
 {
-    if (remotefile)
+    if (remotefile) {
         remotefile->Start();
+	requested = 0;
+    }
 }
 
 // guaranteed to be paused, so don't need to lock this
@@ -360,6 +366,7 @@
         if (remotefile)
         {
             remotefile->Reset();
+	    requested = 0;
         }
         else
         {
@@ -428,43 +435,41 @@
 
     QSocket *sock = rf->getSocket();
 
-    qApp->lock();
-    unsigned int available = sock->bytesAvailable();
-    qApp->unlock();
+    do {
+	int reqsize = 128000;
 
-    while (available < sz) 
-    {
-        int reqsize = 128000;
-
-        if (rf->RequestBlock(reqsize))
-            break;
-
-        zerocnt++;
-        if (zerocnt >= 10)
-        {
-            break;
-        }
-        usleep(100);
-        if (stopreads)
-            break;
+	if (requested < 1500000) { /* 1.5 meg window */
+		/* ask for more data. */
+            if (rf->RequestBlock(reqsize))
+		break;
+	    requested += reqsize;
+	}
 
-        qApp->lock();
-        available = sock->bytesAvailable();
-        qApp->unlock();
-    }
+	if (stopreads)
+	    break;
 
-    qApp->lock();
-    available = sock->bytesAvailable();
-    qApp->unlock();
+	qApp->lock();
+	unsigned int available = sock->bytesAvailable();
+	qApp->unlock();
+
+	if (available < 1) {
+	    usleep(50);
+	    zerocnt++;
+	    if (zerocnt >= 10) {
+		printf("zerocnt gave.\n");
+		break; /* Taking too long??? */
+	    }
+	    continue;
+	}
 
-    if (available >= sz)
-    {
-        qApp->lock();
         ret = sock->readBlock(((char *)data) + tot, sz - tot);
-        qApp->unlock();
+	if (ret < 0)
+	    break;
+
+	tot += ret;
+	requested -= ret;
+    } while (tot < sz);
 
-        tot += ret;
-    }
     return tot;
 }
 
@@ -560,7 +565,7 @@
     used = tfw->BufUsed();
     free = tfw->BufFree();
 
-    ret = (used * 5 > free);
+    ret = (used > free);
 
     pthread_rwlock_unlock(&rwlock);
     return ret;
@@ -650,6 +655,7 @@
         else if (whence == SEEK_CUR)
             readpos += pos;
         totalreadpos = readpos;
+	requested =0;
     }
     else
     {
@@ -670,6 +676,7 @@
                 ret = lseek(fd2, realseek, SEEK_SET);
             }
 	}
+	requested =0;
 
         if (whence == SEEK_SET)
         {
diff -ur mythtv-0.8/libs/libmythtv/RingBuffer.h mythtv-local/libs/libmythtv/RingBuffer.h
--- mythtv-0.8/libs/libmythtv/RingBuffer.h	2003-02-06 06:46:51.000000000 +1100
+++ mythtv-local/libs/libmythtv/RingBuffer.h	2003-05-09 12:00:16.000000000 +1000
@@ -82,6 +82,8 @@
 
     long long wrapcount;
 
+    long long requested;
+
     bool stopreads;
 
     pthread_rwlock_t rwlock;


More information about the mythtv-dev mailing list