[mythtv] Frontend locking/freezing on FF with SD/HD content

Tomi Orava tomimo+mythtv-dev at ncircle.nullnet.fi
Sun Oct 15 13:15:10 UTC 2006


Hi,

>> I've got MythTV 0.20 setup on Gentoo. Occasionally the front end will
>> lockup while fast forwarding, generally this occurs when skipping "in to
>> the future", that is ff'ing into and past the end of the recorded
>> program.
>
> You should have a look at my patch in ticket 2434:
>
> http://svn.mythtv.org/trac/ticket/2434
>
> I don't know if it will help, but it certainly fixes hangs in 'watch
> recordings' while FF/REWding. I think that the LiveTV issue may be a
> different one (I've seen hangs even with this patch applied), but it's
> certainly worth giving it a go.

I personally don't think that your patch is a proper one, due to the fact
that the code in question is a slight mess what comes to locking.
As I haven't been able to get the latest 0.20 to run properly with
other reasons (DVB EIT problems), I did some debugging with 0.19
version with exactly the same problems and found out that it
was possible to hang the frontend just by toggling FF or RW and
play buttons with remote control too fast.

To my understanding there exists a race condition in NuppelVideoPlayer.cpp,
where the method PauseVideo() is being called, but while the call is still
being
done, you press "Play" again and therefore another thread calls
UnPauseVideo()
_before_ the PauseVideo() has hit the line containing a call to
videoThreadPaused.wait(1000) ---> the whole frontend hangs.

I have done some very ugly hack which seems to fix the problem in my case,
but because the code in (at least in 0.19) NuppelVideoPlayer.cpp is little
bit on the messy side what comes to using the variables "pausevideo"
and "video_actually_paused", it isn't very easy to add proper locking
into the code without heavy changes.

The most important thing that the ugly hack below does is to introduce
a condition wait predicate "pause_signal" and therefore make sure that
if the FF is being unpaused before the system reaches the condition wait
in PauseVideo() it will be skipped immediately --> no hanging.

Regards,
Tomi Orava

Index: NuppelVideoPlayer.cpp
===================================================================
--- NuppelVideoPlayer.cpp       (revision 10604)
+++ NuppelVideoPlayer.cpp       (working copy)
@@ -84,6 +84,7 @@
       eof(false),                   m_double_framerate(false),
       m_can_double(false),          paused(false),
       pausevideo(false),            actuallypaused(false),
+      pause_signal(false),
       video_actually_paused(false), playing(false),
       decoder_thread_alive(true),   killplayer(false),
       killvideo(false),             livetv(false),
@@ -326,23 +327,32 @@

 void NuppelVideoPlayer::PauseVideo(bool wait)
 {
+    pauseLock.lock();
     video_actually_paused = false;
     pausevideo = true;
+    pauseLock.unlock();

     if (wait && !video_actually_paused)
     {
-        while (!videoThreadPaused.wait(1000))
+        while (!pause_signal && !videoThreadPaused.wait(1000))
         {
-            if (eof)
+            if (eof) {
+                pause_signal=false;
                 return;
+            }
             VERBOSE(VB_IMPORTANT, "Waited too long for video out to pause");
         }
     }
+    pause_signal=false;
 }

 void NuppelVideoPlayer::UnpauseVideo(void)
 {
+    pauseLock.lock();
     pausevideo = false;
+    pause_signal=true;
+    pauseLock.unlock();
+    videoThreadPaused.wakeAll();
 }
 void NuppelVideoPlayer::SetPrebuffering(bool prebuffer)
@@ -1796,7 +1806,10 @@
         resetvideo = false;
     }

+    pauseLock.lock();
     video_actually_paused = true;
+    pause_signal=true;
+    pauseLock.unlock();
     videoThreadPaused.wakeAll();

     if (videoOutput->IsErrored())
@@ -1897,7 +1910,9 @@

 void NuppelVideoPlayer::DisplayNormalFrame(void)
 {
+    pauseLock.lock();
     video_actually_paused = false;
+    pauseLock.unlock();
     resetvideo = false;

     if (!PrebufferEnoughFrames())
@@ -2091,6 +2106,9 @@

         if (pausevideo)
         {
+            pauseLock.lock();
+            pause_signal=true;
+            pauseLock.unlock();
             videoThreadPaused.wakeAll();
             videofiltersLock.lock();
             videoOutput->ProcessFrame(NULL, osd, videoFilters, pipplayer);


===================================================================
--- NuppelVideoPlayer.h (revision 10604)
+++ NuppelVideoPlayer.h (working copy)
@@ -384,6 +384,8 @@
     QWaitCondition decoderThreadPaused;
     QWaitCondition videoThreadPaused;
     QMutex   vidExitLock;
+    QMutex   pauseLock;
+    bool     pause_signal;
     bool     eof;             ///< At end of file/ringbuffer
     bool     m_double_framerate;///< Output fps is double Video (input) rate
     bool     m_can_double;    ///< VideoOutput capable of doubling frame
rate








-- 




More information about the mythtv-dev mailing list