[mythtv] Solving my performance problems...

Steve Brown sbrown at cortland.com
Fri Dec 19 06:55:25 EST 2003


Isaac Richards wrote:
> 
> 
> Ah well.  I'd still like to see your usleep removal patch, as that'd probably 
> be a good thing to get into CVS.
> 
> Isaac

A patch against the current cvs is attached.

I left in some instrumentation to help you verify it's working as 
advertised.

The qt wait with timeout is busted in my RH9 qt 3.1.1-6. It fails to 
convert the relative time in the parameter to the time of day required 
for the pthread call. It's fixed in Trolltech's 3.3.0b1. I don't know at 
what version they actually made the change.

Also, I added the lock in setPrebuffering. My instrumentation showed it 
being called from both threads.

vbuffers.frameNumber wasn't getting initialized and made some 
instrumentation I added hard to follow. I didn't try to figure out 
whether it's being uninitialized was really a problem.

Hope I haven't broken anything,

Steve
-------------- next part --------------
Index: libs/libmyth/mythcontext.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmyth/mythcontext.h,v
retrieving revision 1.113
diff -u -r1.113 mythcontext.h
--- libs/libmyth/mythcontext.h	16 Dec 2003 05:23:39 -0000	1.113
+++ libs/libmyth/mythcontext.h	19 Dec 2003 11:16:26 -0000
@@ -44,7 +44,7 @@
 #define VERBOSE(mask,args...) \
 do { \
 if ((print_verbose_messages & mask) != 0) \
-    cout << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss") \
+    cout << QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss.zzz") \
          << " " << args << endl; \
 } while (0)
 
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoPlayer.cpp,v
retrieving revision 1.300
diff -u -r1.300 NuppelVideoPlayer.cpp
--- libs/libmythtv/NuppelVideoPlayer.cpp	6 Dec 2003 00:01:45 -0000	1.300
+++ libs/libmythtv/NuppelVideoPlayer.cpp	19 Dec 2003 11:16:28 -0000
@@ -53,8 +53,11 @@
     playing = false;
     decoder_thread_alive = true;
     filename = "output.nuv";
+    prebuffering_lock.lock();
     prebuffering = false;
-
+    prebuffering_wait.wakeAll();
+    prebuffering_lock.unlock();
+	
     vbimode = ' ';
     QString mypage = gContext->GetSetting("VBIpageNr", "888");
     bool valid = false;
@@ -277,12 +280,17 @@
 
 void NuppelVideoPlayer::setPrebuffering(bool prebuffer)
 {
+	prebuffering_lock.lock();
     if (prebuffer != prebuffering)
     {
         prebuffering = prebuffer;
         if (audioOutput && !paused)
             audioOutput->Pause(prebuffering);
     }
+
+	if (!prebuffering)
+		prebuffering_wait.wakeAll();
+	prebuffering_lock.unlock();
 }
 
 void NuppelVideoPlayer::ForceVideoOutputType(VideoOutputType type)
@@ -589,17 +597,26 @@
         return;
     }
 
-    while (!videoOutput->EnoughFreeFrames() && !unsafe)
-    {
-        //cout << "waiting for video buffer to drain.\n";
+    wait_lock.lock();
+    if (!videoOutput->EnoughFreeFrames() && !unsafe)
+	{
+        VERBOSE(VB_PLAYBACK, QString("%1 %2:%3:%4 waiting for video buffer to drain")\
+            .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
         setPrebuffering(false);
-        usleep(2000);
+        if (!videoOutput->availableVideoBuffers_wait.wait(&wait_lock,10000))
+            VERBOSE(VB_PLAYBACK, QString("%1 %2:%3:%4 waiting for video buffer to drain --timed out--")\
+                .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
     }
+    wait_lock.unlock();
 
     decoder->GetFrame(onlyvideo);
 
     if (videoOutput->EnoughDecodedFrames())
+	{
+		VERBOSE(VB_PLAYBACK, QString("%1 %2:%3:%4 prebuffering unpause")\
+            .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
         setPrebuffering(false);
+	}
 }
 
 void NuppelVideoPlayer::ReduceJitter(struct timeval *nexttrigger)
@@ -1231,24 +1248,32 @@
             videoOutput->Show();
             ResetNexttrigger(&nexttrigger);
 
-            //printf("video waiting for unpause\n");
+            VERBOSE(VB_PLAYBACK, QString("%1 %2:%3:%4 waiting for unpause 'pausevideo'")\
+                .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
             usleep(frame_interval);
             continue;
         }
         video_actually_paused = false;
         resetvideo = false;
 
+        prebuffering_lock.lock();
         if (prebuffering)
         {
-            VERBOSE(VB_PLAYBACK, "waiting for prebuffer...");
-            usleep(frame_interval * 4);
+            VERBOSE(VB_PLAYBACK, QString("%1 %2:%3:%4 prebuffering_wait")\
+                .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
+            if (!prebuffering_wait.wait(&prebuffering_lock,10000))
+                VERBOSE(VB_PLAYBACK, QString("%1 %2:%3:%4 prebuffering_wait timed out!!")\
+                    .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
+            prebuffering_lock.unlock();
             ResetNexttrigger(&nexttrigger);
             continue;
         }
+        prebuffering_lock.unlock();
 
         if (!videoOutput->EnoughPrebufferedFrames())
         {
-            VERBOSE(VB_GENERAL, "prebuffering pause");
+            VERBOSE(VB_GENERAL, QString("%1 %2:%3:%4 prebuffering pause")\
+                .arg(pthread_self()).arg(__FILE__).arg(__FUNCTION__).arg(__LINE__));
             setPrebuffering(true); 
             continue;
         }
Index: libs/libmythtv/NuppelVideoPlayer.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/NuppelVideoPlayer.h,v
retrieving revision 1.125
diff -u -r1.125 NuppelVideoPlayer.h
--- libs/libmythtv/NuppelVideoPlayer.h	26 Nov 2003 21:43:02 -0000	1.125
+++ libs/libmythtv/NuppelVideoPlayer.h	19 Dec 2003 11:16:28 -0000
@@ -269,8 +269,13 @@
     int vbipagenr;
     int text_size;
 
+    /* lock to protect wait test and wait */
+    QMutex wait_lock;
+
     /* Video circular buffer */
-    bool prebuffering;	/* don't play until done prebuffering */ 
+    bool prebuffering;	/* don't play until done prebuffering */
+    QMutex prebuffering_lock;
+    QWaitCondition prebuffering_wait;
 
     /* Text circular buffer */
     int wtxt;          /* next slot to write */
Index: libs/libmythtv/videooutbase.cpp
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videooutbase.cpp,v
retrieving revision 1.29
diff -u -r1.29 videooutbase.cpp
--- libs/libmythtv/videooutbase.cpp	16 Dec 2003 02:17:32 -0000	1.29
+++ libs/libmythtv/videooutbase.cpp	19 Dec 2003 11:16:30 -0000
@@ -284,6 +284,7 @@
     video_buflock.lock();
 
     availableVideoBuffers.clear();
+	availableVideoBuffers_wait.wakeAll();
     vbufferMap.clear();
 
     for (int i = 0; i < numbuffers; i++)
@@ -586,6 +587,8 @@
     {
         next = usedVideoBuffers.dequeue();
         busyVideoBuffers.removeRef(next);
+        if (EnoughFreeFrames())
+            availableVideoBuffers_wait.wakeAll();
     }
 
     video_buflock.unlock();
@@ -607,6 +610,8 @@
 {
     video_buflock.lock();
     availableVideoBuffers.enqueue(frame);
+    if(EnoughFreeFrames())
+        availableVideoBuffers_wait.wakeAll();
     video_buflock.unlock();
 }
 
@@ -634,6 +639,8 @@
     {
         availableVideoBuffers.enqueue(buf);
         busyVideoBuffers.removeRef(buf);
+        if (EnoughFreeFrames())
+            availableVideoBuffers_wait.wakeAll();
     }
 
     video_buflock.unlock();
@@ -705,6 +712,7 @@
         availableVideoBuffers.enqueue(&(vbuffers[i]));
         vbufferMap[&(vbuffers[i])] = i;
     }
+    availableVideoBuffers_wait.wakeAll();
 
     for (int i = 0; i < numcreate; i++)
     {
@@ -713,6 +721,7 @@
         vbuffers[i].bpp = vbuffers[i].size = 0;
         vbuffers[i].buf = NULL;
         vbuffers[i].timecode = 0;
+        vbuffers[i].frameNumber = 0;
         vbuffers[i].qscale_table = NULL;
         vbuffers[i].qstride = 0;
     }
@@ -734,12 +743,16 @@
     {
         VideoFrame *buffer = usedVideoBuffers.dequeue();
         availableVideoBuffers.enqueue(buffer);
+        if (EnoughFreeFrames())
+            availableVideoBuffers_wait.wakeAll();
     }
 
     if (usedVideoBuffers.count() > 0)
     {
         VideoFrame *buffer = usedVideoBuffers.dequeue();
         availableVideoBuffers.enqueue(buffer);
+        if (EnoughFreeFrames())
+            availableVideoBuffers_wait.wakeAll();
         vpos = vbufferMap[buffer];
         rpos = vpos;
     }
@@ -1125,4 +1138,3 @@
     }
 */
 }
-
Index: libs/libmythtv/videooutbase.h
===================================================================
RCS file: /var/lib/mythcvs/mythtv/libs/libmythtv/videooutbase.h,v
retrieving revision 1.21
diff -u -r1.21 videooutbase.h
--- libs/libmythtv/videooutbase.h	16 Dec 2003 02:17:32 -0000	1.21
+++ libs/libmythtv/videooutbase.h	19 Dec 2003 11:16:30 -0000
@@ -7,6 +7,7 @@
 #include <qmutex.h>
 #include <qmap.h>
 #include <qptrqueue.h>
+#include <qwaitcondition.h>
 #include <qptrlist.h>
 
 using namespace std;
@@ -83,6 +84,7 @@
     int FreeVideoFrames(void);
 
     bool EnoughFreeFrames(void);
+    QWaitCondition availableVideoBuffers_wait;
     bool EnoughDecodedFrames(void);
     bool EnoughPrebufferedFrames(void);
     


More information about the mythtv-dev mailing list