Mailing List archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[vdr] Re: Buffer Overflows in vdr-1.3.13



Am Samstag, 23. Oktober 2004 19:11 schrieb Gregoire Favre:
> Hello,
>
> is there somewhere a complete patch ?
>
> Thank you very much,

i've seen that tomorrow there will be vdr-1.3.14 but nevertheless i've made 
the patch so i will post it.


Common subdirectories: vdr-1.3.13-orig/PLUGINS and vdr-1.3.13-patched/PLUGINS
diff -uN vdr-1.3.13-orig/dvbdevice.c vdr-1.3.13-patched/dvbdevice.c
--- vdr-1.3.13-orig/dvbdevice.c	2004-10-17 11:10:43.000000000 +0200
+++ vdr-1.3.13-patched/dvbdevice.c	2004-10-23 19:21:22.677674472 +0200
@@ -35,7 +35,7 @@
 
 #define DO_REC_AND_PLAY_ON_PRIMARY_DEVICE 1
 #define DO_MULTIPLE_RECORDINGS 1
-//#define WAIT_FOR_LOCK_AFTER_TUNING 1
+#define TUNER_LOCK_TIMEOUT 5000 // ms
 
 #define DEV_VIDEO         "/dev/video"
 #define DEV_DVB_ADAPTER   "/dev/dvb/adapter"
@@ -78,6 +78,8 @@
   bool useCa;
   time_t startTime;
   eTunerStatus tunerStatus;
+  cMutex mutex;
+  cCondVar locked;
   cCondWait newSet;
   bool SetFrontend(void);
   virtual void Action(void);
@@ -86,7 +88,7 @@
   virtual ~cDvbTuner();
   bool IsTunedTo(const cChannel *Channel) const;
   void Set(const cChannel *Channel, bool Tune, bool UseCa);
-  bool Locked(void) { return tunerStatus >= tsLocked; }
+  bool Locked(int TimeoutMs = 0);
   };
 
 cDvbTuner::cDvbTuner(int Fd_Frontend, int CardIndex, fe_type_t FrontendType, cCiHandler *CiHandler)
@@ -125,7 +127,7 @@
   if (Tune)
      tunerStatus = tsSet;
   else if (tunerStatus == tsCam)
-     tunerStatus = tsTuned;
+     tunerStatus = tsLocked;
   useCa = UseCa;
   if (Channel->Ca() && tunerStatus != tsCam)
      startTime = time(NULL);
@@ -134,6 +136,14 @@
   newSet.Signal();
 }
 
+bool cDvbTuner::Locked(int TimeoutMs)
+{
+  cMutexLock MutexLock(&mutex);
+  if (TimeoutMs && tunerStatus < tsLocked)
+     locked.TimedWait(mutex, TimeoutMs);
+  return tunerStatus >= tsLocked;
+}
+
 static unsigned int FrequencyToHz(unsigned int f)
 {
   while (f && f < 1000000)
@@ -253,22 +263,25 @@
   active = true;
   while (active) {
         Lock();
-        if (tunerStatus == tsSet)
+        if (tunerStatus == tsSet) {
+           dvb_frontend_event event;
+           while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0)
+                 ; // discard stale events
            tunerStatus = SetFrontend() ? tsTuned : tsIdle;
-        if (tunerStatus == tsTuned) {
-           fe_status_t status = fe_status_t(0);
-           CHECK(ioctl(fd_frontend, FE_READ_STATUS, &status));
-           if (status & FE_HAS_LOCK)
-              tunerStatus = tsLocked;
            }
         if (tunerStatus != tsIdle) {
            dvb_frontend_event event;
-           if (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
-              if (event.status & FE_REINIT) {
-                 tunerStatus = tsSet;
-                 esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
+           while (ioctl(fd_frontend, FE_GET_EVENT, &event) == 0) {
+                 if (event.status & FE_REINIT) {
+                    tunerStatus = tsSet;
+                    esyslog("ERROR: frontend %d was reinitialized - re-tuning", cardIndex);
+                    }
+                 if (event.status & FE_HAS_LOCK) {
+                    cMutexLock MutexLock(&mutex);
+                    tunerStatus = tsLocked;
+                    locked.Broadcast();
+                    }
                  }
-              }
            }
         if (ciHandler) {
            if (ciHandler->Process() && useCa) {
@@ -293,7 +306,7 @@
            }
         Unlock();
         // in the beginning we loop more often to let the CAM connection start up fast
-        newSet.Wait((ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
+        newSet.Wait((tunerStatus == tsTuned || ciHandler && (time(NULL) - startTime < 20)) ? 100 : 1000);
         }
 }
 
@@ -746,14 +759,15 @@
   if (TurnOffLivePIDs)
      TurnOffLiveMode();
 
+  // Set the tuner and wait for a lock:
+
   dvbTuner->Set(Channel, DoTune, !EITScanner.UsesDevice(this)); //XXX 1.3: this is an ugly hack - find a cleaner solution//XXX
 
-#ifdef WAIT_FOR_LOCK_AFTER_TUNING
-  //XXX TODO preliminary fix for the "Unknown picture type" error
-  time_t t0 = time(NULL);
-  while (!dvbTuner->Locked() && time(NULL) - t0 < 5)
-        usleep(100);
-#endif
+  if (!dvbTuner->Locked(TUNER_LOCK_TIMEOUT)) {
+     //XXX esyslog("ERROR: no lock for channel %s on device %d", Channel->ToText(), CardIndex() + 1);
+     return false;
+     }
+
   // PID settings:
 
   if (TurnOnLivePIDs) {
Common subdirectories: vdr-1.3.13-orig/libsi and vdr-1.3.13-patched/libsi
Common subdirectories: vdr-1.3.13-orig/patches and vdr-1.3.13-patched/patches
diff -uN vdr-1.3.13-orig/remux.c vdr-1.3.13-patched/remux.c
--- vdr-1.3.13-orig/remux.c	2004-10-16 11:11:52.000000000 +0200
+++ vdr-1.3.13-patched/remux.c	2004-10-23 19:23:37.528174080 +0200
@@ -597,7 +597,7 @@
                Count += l;
                }
             else
-               resultSkipped = i;
+               resultSkipped = i + l;
             if (l > 0)
                i += l - 1; // the loop increments, too
             }
Common subdirectories: vdr-1.3.13-orig/symbols and vdr-1.3.13-patched/symbols
diff -uN vdr-1.3.13-orig/transfer.c vdr-1.3.13-patched/transfer.c
--- vdr-1.3.13-orig/transfer.c	2004-10-16 11:22:58.000000000 +0200
+++ vdr-1.3.13-patched/transfer.c	2004-10-23 19:23:15.217565808 +0200
@@ -65,7 +65,7 @@
         int Count;
         uchar *b = ringBuffer->Get(Count);
         if (b) {
-           if (Count > TRANSFERBUFSIZE * 2 / 3) {
+    	    if (ringBuffer->Available() > TRANSFERBUFSIZE * 2 / 3) {
               // If the buffer runs full, we have no chance of ever catching up
               // since the data comes in at the same rate as it goes out (it's "live").
               // So let's clear the buffer instead of suffering from permanent

Home | Main Index | Thread Index