VDR+DXR3 - stability problems (possible patch)

Message ID 428A73C1.7040204@uklinux.net
State New
Headers

Commit Message

Jon Burgess May 17, 2005, 10:44 p.m. UTC
  Mikolaj Tutak wrote:
> Yes, I have this. Menu shows mixed trashes (swaped lines etc.) and VDR 
> hangs for long time. Maybe I take snapshot some time.

Yes this occasional freeze with garbled OSD happens from time to time 
and seems to be much more frequent when there is no Video data (e.g. 
with the mp3 plugin). I don't know any way of fixing these problems.

I've been working on the problems that occur with occasional bursts of 
interference which can occasionally cause the output to lockup. I've 
made a few changes which seem to help a lot with getting the dxr3plugin 
to recover when this occurs.

Can you try adding this patch to the dxr3plugin and see if it helps?

	Jon
  

Comments

Allan Guild May 18, 2005, 8:59 a.m. UTC | #1
Jon,

I built the plugin last night with two of your patches:

1. The pthread_setschedparam idea suggested on em8300-devel
2. The timeout patch posted on this list a few days ago

This looks like a replacement to them both with some additional changes
to dxr3demuxdevice.  Have I read this correctly?

I also notice that there is no change to VDR's thread.c in this patch.
Do you think that this is un-necessary?  I am keen to maintain a single
VDR tree and was worried that the change to thread.c might have a
negative effect on slower machines using the Xine plugin (I have a
couple of these).

Sorry for all the questions.  I really appreciate all your posts and
patches for the DXR3 plugin, as well as those of Luca, Ville, Martin and
others.  For the first time yesterday (as I hadn't updated the plugin in
a month or so), I was able to play Tetris using the OSD ;)

I will try the updated patch in the next couple of days and post back
any findings.

Best wishes,

Allan

On Tue, 2005-05-17 at 23:44 +0100, Jon Burgess wrote:
> Mikolaj Tutak wrote:
> > Yes, I have this. Menu shows mixed trashes (swaped lines etc.) and VDR 
> > hangs for long time. Maybe I take snapshot some time.
> 
> Yes this occasional freeze with garbled OSD happens from time to time 
> and seems to be much more frequent when there is no Video data (e.g. 
> with the mp3 plugin). I don't know any way of fixing these problems.
> 
> I've been working on the problems that occur with occasional bursts of 
> interference which can occasionally cause the output to lockup. I've 
> made a few changes which seem to help a lot with getting the dxr3plugin 
> to recover when this occurs.
> 
> Can you try adding this patch to the dxr3plugin and see if it helps?
> 
> 	Jon
> 
> _______________________________________________
> vdr mailing list
> vdr@linuxtv.org
> http://www.linuxtv.org/cgi-bin/mailman/listinfo/vdr
  
Jon Burgess May 18, 2005, 9:09 p.m. UTC | #2
Allan Guild wrote:
> This looks like a replacement to them both with some additional changes
> to dxr3demuxdevice.  Have I read this correctly?

Mostly correct, but there is an additonal "return NULL" in the push 
timeout path. The changes in the dxr3demuxdevice code make it abort if 
the push() code returns NULL.

I didn't want to send a patch over the top other changes, so I packaged 
all the related changes together and generated the diff vs the vanilla 
dxr3plugin code.

> I also notice that there is no change to VDR's thread.c in this patch.

The removal of realtime scheduling in thread.c was to help identify and 
debug the errant code which was hogging the CPU and making it appear 
like the machine had locked up. I don't think this change is useful in 
the normal use unless your machine still keeps locking up.

	Jon
  
Mikolaj Tutak May 19, 2005, 9:09 a.m. UTC | #3
Jon Burgess napisa?(a):

> Yes this occasional freeze with garbled OSD happens from time to time 
> and seems to be much more frequent when there is no Video data (e.g. 
> with the mp3 plugin). I don't know any way of fixing these problems.

Probably sending "prepared" empty frame with/before OSD will help (when 
there is no real data). Similar to "NoSignal.pes" in vdr-xine. I'm 
afraid that DXR3 do not like OSD data without valid primary stream.

> I've been working on the problems that occur with occasional bursts of 
> interference which can occasionally cause the output to lockup. I've 
> made a few changes which seem to help a lot with getting the 
> dxr3plugin to recover when this occurs. 

> Can you try adding this patch to the dxr3plugin and see if it helps?

I tested your patch with my DXR3 setup (newest microdode 0x2e)
I have two "fifo full" issues (without valid signal):
1. vdr exits, so I have to start it again
2. OSD garbaged (I can send you screenshot), "fifo full" message appeard 
in syslog, but vdr didn't exit. I recovers by pressing "menu"->4 
(recordings)->green (rewind), but the stream plays jerky, but replaying 
sequence stop->menu->4->green helps and the strem looked OK.
  

Patch

diff --exclude='*.o' -urw /home/jburgess/dvb/vdr-1.3.23/PLUGINS/src/dxr3/dxr3demuxdevice.c dxr3/dxr3demuxdevice.c
--- /home/jburgess/dvb/vdr-1.3.23/PLUGINS/src/dxr3/dxr3demuxdevice.c	2005-04-19 19:19:37.000000000 +0100
+++ dxr3/dxr3demuxdevice.c	2005-05-17 22:36:39.000000000 +0100
@@ -396,6 +396,9 @@ 
 		    m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize());
 		    while (!Poll(100));
 		    cFixedLengthFrame* pTempFrame = m_vBuf.Push(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, ftVideo);
+		    
+		    if (!pTempFrame) /* Push Timeout */
+			throw (cDxr3PesFrame::PES_GENERAL_ERROR);
 		    pTempFrame->SetAspectRatio(pesFrame.GetAspectRatio());
 
 		    m_aBuf.WakeUp();
@@ -422,6 +425,10 @@ 
 			m_dxr3Device.SetHorizontalSize(pesFrame.GetHorizontalSize());
 			m_dxr3Device.SetVerticalSize(pesFrame.GetVerticalSize());
 			cFixedLengthFrame* pTempFrame = m_vBuf.Push(pesFrame.GetEsStart(), (int) (pesFrame.GetEsLength()), pts, ftVideo);
+
+			if (!pTempFrame) /* Push Timeout */
+			    throw (cDxr3PesFrame::PES_GENERAL_ERROR);
+
 			pTempFrame->SetAspectRatio(pesFrame.GetAspectRatio());
 
 			if (m_synchState == DXR3_DEMUX_AUDIO_SYNCHED)
diff -urw ref-/dxr3/dxr3outputthread.c dxr3/dxr3outputthread.c
--- ref-/dxr3/dxr3outputthread.c	2005-04-19 19:19:38.000000000 +0100
+++ dxr3/dxr3outputthread.c	2005-05-08 03:04:21.000000000 +0100
@@ -95,10 +95,12 @@ 
     sched_param temp;
     temp.sched_priority = 2;
 
+#if 0
     if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp))
     {
 	cLog::Instance() << "cDxr3AudioOutThread::Action(): Error can't set priority\n";
     }
+#endif
 
     while (!GetStopSignal())
     {
@@ -189,12 +191,12 @@ 
 
     sched_param temp;
     temp.sched_priority = 1;
-
+#if 0
     if (!pthread_setschedparam(pthread_self(), SCHED_RR, &temp))
     {
 	cLog::Instance() << "cDxr3VideoOutThread::Action(): Error can't set priority\n";
     }
-
+#endif
     while (!GetStopSignal())
     {
 	cFixedLengthFrame* pNext = m_buffer.Get();
diff -urw ref-/dxr3/dxr3syncbuffer.c dxr3/dxr3syncbuffer.c
--- ref-/dxr3/dxr3syncbuffer.c	2005-04-19 19:19:38.000000000 +0100
+++ dxr3/dxr3syncbuffer.c	2005-05-17 22:37:52.000000000 +0100
@@ -26,6 +26,7 @@ 
 */
 
 #include <unistd.h>
+#include <sys/time.h>
 #include "dxr3syncbuffer.h"
 #include "dxr3memcpy.h"
 
@@ -174,15 +175,17 @@ 
 }
 
 // ==================================
-const int BUFFER_LIMIT = 5;
-const int BUFFER_LIMIT_2 = 10;
+const int BUFFER_LIMIT = 5;    // 5
+const int BUFFER_LIMIT_2 = 10; // 10
 
 // ==================================
 bool cDxr3SyncBuffer::Poll(int TimeoutMs)
 {
     bool retVal = true;
     uint32_t currTime = m_dxr3Device.GetSysClock();
+    struct timeval tv_start, tv;
     m_bPollSync = true;
+    gettimeofday(&tv_start, NULL);
     if (m_demuxMode == DXR3_DEMUX_REPLAY_MODE)
     {
 	if (Available() >= Size() - (Size()*BUFFER_LIMIT/100))
@@ -192,10 +195,20 @@ 
 		   ((m_dxr3Device.GetSysClock() - currTime) <
 		    ((uint32_t)TimeoutMs * (uint32_t)45)))
 	    {
+		int d_s, d_us, ms;
 		m_bPutBlock = true;
 		EnableGet();
 		m_bWaitPts = false;
 		WaitForPut();
+ 		gettimeofday(&tv, NULL);
+		d_s  = tv.tv_sec  - tv_start.tv_sec;
+		d_us = tv.tv_usec - tv_start.tv_usec;
+		ms = d_s * 1000 + d_us / 1000;
+		if (ms > TimeoutMs * 2) {
+		    cLog::Instance() << "Secondary timeout\n";
+		    printf("Secondary timeout\n");
+		    break;
+		}
 	    }
 	    if (Available() >= Size() - (Size()*BUFFER_LIMIT_2)/100)
 	    {
@@ -211,6 +224,8 @@ 
 cFixedLengthFrame* cDxr3SyncBuffer::Push(const uint8_t* pStart, int length, uint32_t pts, eFrameType type)  throw (eSyncBufferException)
 {
     int lastIndex = 0;
+    struct timeval tv_start, tv;
+    gettimeofday(&tv_start, NULL);
 
     switch (m_demuxMode)
     {
@@ -223,10 +238,21 @@ 
 
 	while ((Available() >= Size() - (Size()*10)/100))
 	{
+	    int d_s, d_us, ms;
 	    m_bPutBlock = true;
 	    EnableGet();
 	    m_bWaitPts = false;
 	    WaitForPut();
+	    gettimeofday(&tv, NULL);
+	    d_s  = tv.tv_sec  - tv_start.tv_sec;
+	    d_us = tv.tv_usec - tv_start.tv_usec;
+	    ms = d_s * 1000 + d_us / 1000;
+	    if (ms > 2000) {
+		cLog::Instance() << "Push timeout\n";
+		printf("Push timeout\n");
+		return NULL;
+		//break;
+	    }
 	}
 
 #if VDRVERSNUM < 10313