VDSB Video Data Stream Broken

Message ID 43BE4C4E.8000501@cadsoft.de
State New
Headers

Commit Message

Klaus Schmidinger Jan. 6, 2006, 10:54 a.m. UTC
Martin Schoenbeck wrote:
> Hi Klaus,
> 
> Klaus Schmidinger schrieb:
> 
>> Of course, that's what it is - I should have seen that by the
>> 20 seconds interval.
> 
> 
> Ok, so the timeouts are OK, right?
> 
>>> AFAIK not on two cards. We see and hear under certain conditions (I 
>>> assume, it happens, when then retuning is on the primary device) sort 
>>> of glitches any several seconds. But these glitches are some 
>>> milliseconds, not two seconds.
>>
>>
>> Is that a new effect, caused by the tuner timeout patch?
>> If so, was it also there with Reinhard's original patch?
> 
> 
> I didn't notice it with Reinhard's patch, but I'm not sure about that. I 
> noticed a short distortion this morning at a time, where tuner 1 and 
> tuner 2 announced timeouts, but AFAIK the primaryDVB 1 uses tuner 0, 
> isn't it? And there were no entries at all with tuner 0 until we started 
> a recording.

Maybe there's a problem with your multiswitch?
When the second or third device changes the transponder, there shouldn't
be any interference with the first device.

>>> I took 4 seconds and will report.
> 
> 
>> Ok.
> 
> 
> The timeouts didn't go, but I assume, that's normal, given the EPG scan 
> scanning. Is the EPG scan running around the clock, if there is a free 
> device other than the primary device?

Yes.

I have attached a slightly modified version of the patch, which
avoids error messages like

   ERROR (dvbdevice.c,157): Value too large for defined data type

when clearing the event queue. It also returns the current frontend status
even if there was no event, and logs the channel number and transponder
in case of a timeout. As far as I can see the timeouts always happen
on transponders that are currently not broadcasting, or use very low
symbol rates, which my full featured second device can't handle.

Klaus
  

Comments

Thomas Rausch Jan. 6, 2006, 12:16 p.m. UTC | #1
I controlled for safety's sake still times dvbdevice.c against the 
original. I have still the Patch:

--------------------------------------------
    //XXX workaround for addition live audio PIDs:
    if (ciHandler) {
       ciHandler->SetPid(Channel->Apid(1), true);
       ciHandler->SetPid(Channel->Dpid(0), true);
       }
--------------------------------------------

in it.

Is still necessary?

Thomas

PS: I exchanged the Patch 4 against 5. But yesterday unfortunately not 
much time had. Today the long term test (with many recordings) comes back.
  
Klaus Schmidinger Jan. 6, 2006, 12:21 p.m. UTC | #2
Thomas Rausch wrote:
> I controlled for safety's sake still times dvbdevice.c against the 
> original. I have still the Patch:
> 
> --------------------------------------------
>    //XXX workaround for addition live audio PIDs:
>    if (ciHandler) {
>       ciHandler->SetPid(Channel->Apid(1), true);
>       ciHandler->SetPid(Channel->Dpid(0), true);
>       }
> --------------------------------------------
> 
> in it.
> 
> Is still necessary?

Yes, it is. Since there are still several problems to solve
with multiple CAM recordings, it will stay this way for version 1.4.

Klaus
  
Martin Schoenbeck Jan. 6, 2006, 1:35 p.m. UTC | #3
Hi Klaus,

Klaus Schmidinger schrieb:
> Maybe there's a problem with your multiswitch?
> When the second or third device changes the transponder, there shouldn't
> be any interference with the first device.

I don't know. But the switching did occur before this patch, too, didn't 
it? I'll investigate further.

> I have attached a slightly modified version of the patch, which
> avoids error messages like
> 
>   ERROR (dvbdevice.c,157): Value too large for defined data type
> 
> when clearing the event queue. It also returns the current frontend status
> even if there was no event, and logs the channel number and transponder
> in case of a timeout. As far as I can see the timeouts always happen
> on transponders that are currently not broadcasting, or use very low
> symbol rates, which my full featured second device can't handle.

This additional output makes it clearer: what is channel 0? And 'Al 
Jazeera' or a  program a channel 1673 indeed is nothing, I regularly 
need to receive. ;-)

At least this UPT and VDSB, which annoy me since 1.3.xx, have gone.

Martin
  
Klaus Schmidinger Jan. 6, 2006, 1:40 p.m. UTC | #4
Martin Schoenbeck wrote:
> Hi Klaus,
> 
> Klaus Schmidinger schrieb:
> 
>> Maybe there's a problem with your multiswitch?
>> When the second or third device changes the transponder, there shouldn't
>> be any interference with the first device.
> 
> 
> I don't know. But the switching did occur before this patch, too, didn't 
> it? I'll investigate further.

The EPG scan hasn't changed by this patch, so there shouldn't be
a difference in that area with or without the patch.

>> I have attached a slightly modified version of the patch, which
>> avoids error messages like
>>
>>   ERROR (dvbdevice.c,157): Value too large for defined data type
>>
>> when clearing the event queue. It also returns the current frontend 
>> status
>> even if there was no event, and logs the channel number and transponder
>> in case of a timeout. As far as I can see the timeouts always happen
>> on transponders that are currently not broadcasting, or use very low
>> symbol rates, which my full featured second device can't handle.
> 
> 
> This additional output makes it clearer: what is channel 0?

When a new transponder is found in the NIT data it doesn't have any
channel numbers yet, therefore the 0.

> And 'Al
> Jazeera' or a  program a channel 1673 indeed is nothing, I regularly 
> need to receive. ;-)
> 
> At least this UPT and VDSB, which annoy me since 1.3.xx, have gone.

Very good.

Klaus
  
Thomas Rausch Jan. 6, 2006, 4:57 p.m. UTC | #5
Klaus Schmidinger schrieb:

> Martin Schoenbeck wrote:
>
>> At least this UPT and VDSB, which annoy me since 1.3.xx, have gone.
>
> Very good. 

I had straight an ARM-Crash because of an GOB error in a recording. I 
want to leave long the VDR without errors continuous to 48 hours (with 
many recordings) before I can say that there is no more error also with 
my VDR.

Thomas
  
Udo Richter Jan. 6, 2006, 5:32 p.m. UTC | #6
Klaus Schmidinger wrote:
> I have attached a slightly modified version of the patch, which
> avoids error messages like
> 
>   ERROR (dvbdevice.c,157): Value too large for defined data type
> 
> when clearing the event queue. It also returns the current frontend status
> even if there was no event, and logs the channel number and transponder
> in case of a timeout. As far as I can see the timeouts always happen
> on transponders that are currently not broadcasting, or use very low
> symbol rates, which my full featured second device can't handle.

For me, I'm currently getting errors for tp 10773h, 10832h, 10861h,
10920h, 11479v, 11914h, 12441v and 12522v. The four low-band
transponders are known PITA of my card, and the four high-band
transponders are empty according to lyngsat.


One case looks like the lost lock state needs additional resetting on
transponder change:

18:22:09 vdr[]: ERROR: frontend 1 lost lock on channel 705, tp 110920
18:22:11 vdr[]: frontend 1 regained lock on channel 347, tp 111720

There were no other messages between these two.

Cheers,

Udo
  
Klaus Schmidinger Jan. 6, 2006, 6:07 p.m. UTC | #7
Udo Richter wrote:
> Klaus Schmidinger wrote:
> 
>>I have attached a slightly modified version of the patch, which
>>avoids error messages like
>>
>>  ERROR (dvbdevice.c,157): Value too large for defined data type
>>
>>when clearing the event queue. It also returns the current frontend status
>>even if there was no event, and logs the channel number and transponder
>>in case of a timeout. As far as I can see the timeouts always happen
>>on transponders that are currently not broadcasting, or use very low
>>symbol rates, which my full featured second device can't handle.
> 
> 
> For me, I'm currently getting errors for tp 10773h, 10832h, 10861h,
> 10920h, 11479v, 11914h, 12441v and 12522v. The four low-band
> transponders are known PITA of my card, and the four high-band
> transponders are empty according to lyngsat.
> 
> 
> One case looks like the lost lock state needs additional resetting on
> transponder change:
> 
> 18:22:09 vdr[]: ERROR: frontend 1 lost lock on channel 705, tp 110920
> 18:22:11 vdr[]: frontend 1 regained lock on channel 347, tp 111720
> 
> There were no other messages between these two.
> 
> Cheers,
> 
> Udo

Incidently I had already added the necessary source line, but
then I thought it might not be that bad to have that "regained"
message, because otherwise there would be a "lost lock" message
in the log without any "regained lock", even if in fact the lock was
actually regained.

Klaus
  
Martin Schoenbeck Jan. 7, 2006, 10:32 p.m. UTC | #8
Hi Klaus,

Klaus Schmidinger schrieb:
>>> Maybe there's a problem with your multiswitch?
>>> When the second or third device changes the transponder, there shouldn't
>>> be any interference with the first device.
>>
>> I don't know. But the switching did occur before this patch, too, 
>> didn't it? I'll investigate further.
> 
> The EPG scan hasn't changed by this patch, so there shouldn't be
> a difference in that area with or without the patch.

The problem has gone with the latest patch. I'd guess, it was the 
massive logging, when retuning, but the card was not running in transfer 
mode.

So, whatever it was, vdr nearly runs as expected. But sometimes, 
probably when the audio format changed, there is a sort of ...
sorry, it's difficult to describe even in german, so I don't try it in 
english.

Gurgeln, aber zwei Oktaven höher. Oder Rascheln. Irgendwas dazwischen.

It's about as loud as the normal tone. About one second long.

Martin
  

Patch

--- dvbdevice.c	2005/11/26 13:23:11	1.138
+++ dvbdevice.c	2006/01/06 10:34:15
@@ -47,6 +40,13 @@ 
 #define DEV_DVB_AUDIO     "audio"
 #define DEV_DVB_CA        "ca"
 
+#define DVBS_TUNE_TIMEOUT  2000 //ms
+#define DVBS_LOCK_TIMEOUT  2000 //ms
+#define DVBC_TUNE_TIMEOUT  5000 //ms
+#define DVBC_LOCK_TIMEOUT  2000 //ms
+#define DVBT_TUNE_TIMEOUT  9000 //ms
+#define DVBT_LOCK_TIMEOUT  2000 //ms
+
 class cDvbName {
 private:
   char buffer[PATH_MAX];
@@ -73,6 +73,9 @@ 
   enum eTunerStatus { tsIdle, tsSet, tsTuned, tsLocked };
   int fd_frontend;
   int cardIndex;
+  int tuneTimeout;
+  int lockTimeout;
+  time_t lastTimeoutReport;
   fe_type_t frontendType;
   cCiHandler *ciHandler;
   cChannel channel;
@@ -81,7 +84,7 @@ 
   cMutex mutex;
   cCondVar locked;
   cCondVar newSet;
-  bool GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs = 0);
+  bool GetFrontendStatus(fe_status_t &Status, int TimeoutMs = 0);
   bool SetFrontend(void);
   virtual void Action(void);
 public:
@@ -98,6 +101,9 @@ 
   cardIndex = CardIndex;
   frontendType = FrontendType;
   ciHandler = CiHandler;
+  tuneTimeout = 0;
+  lockTimeout = 0;
+  lastTimeoutReport = 0;
   diseqcCommands = NULL;
   tunerStatus = tsIdle;
   if (frontendType == FE_QPSK)
@@ -125,6 +131,7 @@ 
   if (Tune)
      tunerStatus = tsSet;
   channel = *Channel;
+  lastTimeoutReport = 0;
   newSet.Broadcast();
 }
 
@@ -140,26 +147,18 @@ 
   return tunerStatus >= tsLocked;
 }
 
-bool cDvbTuner::GetFrontendEvent(dvb_frontend_event &Event, int TimeoutMs)
+bool cDvbTuner::GetFrontendStatus(fe_status_t &Status, int TimeoutMs)
 {
   if (TimeoutMs) {
-     struct pollfd pfd;
-     pfd.fd = fd_frontend;
-     pfd.events = POLLIN | POLLPRI;
-     do {
-        int stat = poll(&pfd, 1, TimeoutMs);
-        if (stat == 1)
-           break;
-        if (stat < 0) {
-           if (errno == EINTR)
-              continue;
-           esyslog("ERROR: frontend %d poll failed: %m", cardIndex);
-           }
-        return false;
-        } while (0);
+     cPoller Poller(fd_frontend);
+     if (Poller.Poll(TimeoutMs)) {
+        dvb_frontend_event Event;
+        while (ioctl(fd_frontend, FE_GET_EVENT, &Event) == 0)
+              ; // just to clear the event queue - we'll read the actual status below
+        }
      }
   do {
-     int stat = ioctl(fd_frontend, FE_GET_EVENT, &Event);
+     int stat = ioctl(fd_frontend, FE_READ_STATUS, &Status);
      if (stat == 0)
         return true;
      if (stat < 0) {
@@ -245,6 +244,9 @@ 
          Frontend.inversion = fe_spectral_inversion_t(channel.Inversion());
          Frontend.u.qpsk.symbol_rate = channel.Srate() * 1000UL;
          Frontend.u.qpsk.fec_inner = fe_code_rate_t(channel.CoderateH());
+
+         tuneTimeout = DVBS_TUNE_TIMEOUT;
+         lockTimeout = DVBS_LOCK_TIMEOUT;
          }
          break;
     case FE_QAM: { // DVB-C
@@ -256,6 +258,9 @@ 
          Frontend.u.qam.symbol_rate = channel.Srate() * 1000UL;
          Frontend.u.qam.fec_inner = fe_code_rate_t(channel.CoderateH());
          Frontend.u.qam.modulation = fe_modulation_t(channel.Modulation());
+
+         tuneTimeout = DVBC_TUNE_TIMEOUT;
+         lockTimeout = DVBC_LOCK_TIMEOUT;
          }
          break;
     case FE_OFDM: { // DVB-T
@@ -271,6 +276,9 @@ 
          Frontend.u.ofdm.transmission_mode = fe_transmit_mode_t(channel.Transmission());
          Frontend.u.ofdm.guard_interval = fe_guard_interval_t(channel.Guard());
          Frontend.u.ofdm.hierarchy_information = fe_hierarchy_t(channel.Hierarchy());
+
+         tuneTimeout = DVBT_TUNE_TIMEOUT;
+         lockTimeout = DVBT_LOCK_TIMEOUT;
          }
          break;
     default:
@@ -286,30 +294,54 @@ 
 
 void cDvbTuner::Action(void)
 {
-  dvb_frontend_event event;
+  cTimeMs Timer;
+  bool LostLock = false;
+  fe_status_t Status = (fe_status_t)0;
   while (Running()) {
-        bool hasEvent = GetFrontendEvent(event, 1);
-
+        fe_status_t NewStatus;
+        if (GetFrontendStatus(NewStatus, 10))
+           Status = NewStatus;
         cMutexLock MutexLock(&mutex);
         switch (tunerStatus) {
           case tsIdle:
                break;
           case tsSet:
-               if (hasEvent)
-                  continue;
                tunerStatus = SetFrontend() ? tsTuned : tsIdle;
+               Timer.Set(tuneTimeout);
                continue;
           case tsTuned:
-          case tsLocked:
-               if (hasEvent) {
-                  if (event.status & FE_REINIT) {
-                     tunerStatus = tsSet;
-                     esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
+               if (Timer.TimedOut()) {
+                  tunerStatus = tsSet;
+                  diseqcCommands = NULL;
+                  if (time(NULL) - lastTimeoutReport > 60) { // let's not get too many of these
+                     esyslog("ERROR: frontend %d timed out while tuning to channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder());
+                     lastTimeoutReport = time(NULL);
                      }
-                  if (event.status & FE_HAS_LOCK) {
-                     tunerStatus = tsLocked;
-                     locked.Broadcast();
+                  continue;
+                  }
+          case tsLocked:
+               if (Status & FE_REINIT) {
+                  tunerStatus = tsSet;
+                  diseqcCommands = NULL;
+                  esyslog("ERROR: frontend %d was reinitialized", cardIndex);
+                  lastTimeoutReport = 0;
+                  continue;
+                  }
+               else if (Status & FE_HAS_LOCK) {
+                  if (LostLock) {
+                     esyslog("frontend %d regained lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder());
+                     LostLock = false;
                      }
+                  tunerStatus = tsLocked;
+                  locked.Broadcast();
+                  lastTimeoutReport = 0;
+                  }
+               else if (tunerStatus == tsLocked) {
+                  LostLock = true;
+                  esyslog("ERROR: frontend %d lost lock on channel %d, tp %d", cardIndex, channel.Number(), channel.Transponder());
+                  tunerStatus = tsTuned;
+                  Timer.Set(lockTimeout);
+                  lastTimeoutReport = 0;
                   continue;
                   }
           }