[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