diff -u -N -r vdr_1.4.5_orig/device.c vdr_1.4.5_eddi/device.c
--- vdr_1.4.5_orig/device.c	2006-09-03 12:13:25.000000000 +0200
+++ vdr_1.4.5_eddi/device.c	2007-02-08 00:16:56.000000000 +0100
@@ -143,13 +143,19 @@
 int cDevice::numDevices = 0;
 int cDevice::useDevice = 0;
 int cDevice::nextCardIndex = 0;
+int cDevice::forceCardIndex = -1;
 int cDevice::currentChannel = 1;
 cDevice *cDevice::device[MAXDEVICES] = { NULL };
 cDevice *cDevice::primaryDevice = NULL;
 
 cDevice::cDevice(void)
 {
-  cardIndex = nextCardIndex++;
+  esyslog("cDevice Constructor");
+
+  if (forceCardIndex >=0)
+    cardIndex = forceCardIndex;
+  else
+    cardIndex = nextCardIndex++;
 
   SetDescription("receiver on device %d", CardIndex() + 1);
 
@@ -174,14 +180,20 @@
   for (int i = 0; i < MAXRECEIVERS; i++)
       receiver[i] = NULL;
 
-  if (numDevices < MAXDEVICES)
-     device[numDevices++] = this;
-  else
-     esyslog("ERROR: too many devices!");
+  if (forceCardIndex >=0)
+       device[cardIndex] = this;
+  else {
+    if (numDevices < MAXDEVICES)
+       device[numDevices++] = this;
+    else
+       esyslog("ERROR: too many devices!");
+  }
+  esyslog("cDevice Constructor: cardIndex=%d", cardIndex);
 }
 
 cDevice::~cDevice()
 {
+  esyslog("cDevice Destructor");
   Detach(player);
   for (int i = 0; i < MAXRECEIVERS; i++)
       Detach(receiver[i]);
@@ -192,6 +204,7 @@
   delete eitFilter;
   delete sectionHandler;
   delete pesAssembler;
+  esyslog("cDevice Destructor: cardIndex=%d", cardIndex);
 }
 
 bool cDevice::WaitForAllDevicesReady(int Timeout)
diff -u -N -r vdr_1.4.5_orig/device.h vdr_1.4.5_eddi/device.h
--- vdr_1.4.5_orig/device.h	2006-06-15 11:32:48.000000000 +0200
+++ vdr_1.4.5_eddi/device.h	2007-02-08 00:24:59.000000000 +0100
@@ -139,6 +139,7 @@
          ///< Must be called at the end of the program.
 private:
   static int nextCardIndex;
+  static int forceCardIndex;
   int cardIndex;
 protected:
   cDevice(void);
@@ -167,6 +168,7 @@
          ///< device (On = false), it should do so in this function.
 public:
   bool IsPrimaryDevice(void) const { return this == primaryDevice; }
+  void ForceCardIndex(int n) const { forceCardIndex = n; }
   int CardIndex(void) const { return cardIndex; }
          ///< Returns the card index of this device (0 ... MAXDEVICES - 1).
   int DeviceNumber(void) const;
diff -u -N -r vdr_1.4.5_orig/dvbdevice.c vdr_1.4.5_eddi/dvbdevice.c
--- vdr_1.4.5_orig/dvbdevice.c	2006-08-14 11:38:32.000000000 +0200
+++ vdr_1.4.5_eddi/dvbdevice.c	2007-02-08 01:06:13.000000000 +0100
@@ -47,22 +47,25 @@
 #define DVBT_TUNE_TIMEOUT  9000 //ms
 #define DVBT_LOCK_TIMEOUT  2000 //ms
 
+cDvbDevice *dvbDevice[MAXDVBFRONTENDS] = { NULL };
+
 class cDvbName {
 private:
   char buffer[PATH_MAX];
 public:
-  cDvbName(const char *Name, int n) {
-    snprintf(buffer, sizeof(buffer), "%s%d/%s%d", DEV_DVB_ADAPTER, n, Name, 0);
+  cDvbName(const char *Name, int adapter, int frontend) {
+    snprintf(buffer, sizeof(buffer), "%s%d/%s%d", DEV_DVB_ADAPTER, adapter, Name, frontend);
     }
   const char *operator*() { return buffer; }
   };
 
-static int DvbOpen(const char *Name, int n, int Mode, bool ReportError = false)
+static int DvbOpen(const char *Name, int adapter, int frontend, int Mode, bool ReportError = false)
 {
-  const char *FileName = *cDvbName(Name, n);
+  const char *FileName = *cDvbName(Name, adapter, frontend);
   int fd = open(FileName, Mode);
   if (fd < 0 && ReportError)
      LOG_ERROR_STR(FileName);
+  esyslog("DvbOpen: %s", FileName);
   return fd;
 }
 
@@ -358,7 +361,7 @@
 int cDvbDevice::devVideoOffset = -1;
 int cDvbDevice::setTransferModeForDolbyDigital = 1;
 
-cDvbDevice::cDvbDevice(int n)
+cDvbDevice::cDvbDevice(int adapter, int frontend)
 {
   dvbTuner = NULL;
   frontendType = fe_type_t(-1); // don't know how else to initialize this - there is no FE_UNKNOWN
@@ -368,14 +371,14 @@
 
   // Devices that are present on all card types:
 
-  int fd_frontend = DvbOpen(DEV_DVB_FRONTEND, n, O_RDWR | O_NONBLOCK);
+  fd_frontend = DvbOpen(DEV_DVB_FRONTEND, adapter, frontend, O_RDWR | O_NONBLOCK);
 
   // Devices that are only present on cards with decoders:
 
-  fd_osd      = DvbOpen(DEV_DVB_OSD,    n, O_RDWR);
-  fd_video    = DvbOpen(DEV_DVB_VIDEO,  n, O_RDWR | O_NONBLOCK);
-  fd_audio    = DvbOpen(DEV_DVB_AUDIO,  n, O_RDWR | O_NONBLOCK);
-  fd_stc      = DvbOpen(DEV_DVB_DEMUX,  n, O_RDWR);
+  fd_osd      = DvbOpen(DEV_DVB_OSD,    adapter, frontend, O_RDWR);
+  fd_video    = DvbOpen(DEV_DVB_VIDEO,  adapter, frontend, O_RDWR | O_NONBLOCK);
+  fd_audio    = DvbOpen(DEV_DVB_AUDIO,  adapter, frontend, O_RDWR | O_NONBLOCK);
+  fd_stc      = DvbOpen(DEV_DVB_DEMUX,  adapter, frontend, O_RDWR);
 
   // The DVR device (will be opened and closed as needed):
 
@@ -420,59 +423,83 @@
      dvb_frontend_info feinfo;
      if (ioctl(fd_frontend, FE_GET_INFO, &feinfo) >= 0) {
         frontendType = feinfo.type;
-        ciHandler = cCiHandler::CreateCiHandler(*cDvbName(DEV_DVB_CA, n));
+        ciHandler = cCiHandler::CreateCiHandler(*cDvbName(DEV_DVB_CA, adapter, frontend));
+        esyslog("cDvbDevice: CardIndex=%d", CardIndex());
         dvbTuner = new cDvbTuner(fd_frontend, CardIndex(), frontendType, ciHandler);
         }
      else
         LOG_ERROR;
      }
   else
-     esyslog("ERROR: can't open DVB device %d", n);
+     esyslog("ERROR: can't open DVB adapter %d - frontend %d", adapter, frontend);
 
   StartSectionHandler();
 }
 
 cDvbDevice::~cDvbDevice()
 {
+  esyslog("~cDvbDevice()"); 
   delete spuDecoder;
   delete dvbTuner;
+  close(fd_stc);
+  close(fd_audio);
+  close(fd_video);
+  close(fd_osd);
+  close(fd_frontend);
   // We're not explicitly closing any device files here, since this sometimes
   // caused segfaults. Besides, the program is about to terminate anyway...
 }
 
-bool cDvbDevice::Probe(const char *FileName)
+int cDvbDevice::Probe(const char *FileName)
 {
   if (access(FileName, F_OK) == 0) {
      dsyslog("probing %s", FileName);
      int f = open(FileName, O_RDONLY);
      if (f >= 0) {
         close(f);
-        return true;
         }
      else if (errno != ENODEV && errno != EINVAL)
         LOG_ERROR_STR(FileName);
      }
   else if (errno != ENOENT)
      LOG_ERROR_STR(FileName);
-  return false;
+  return errno;
 }
 
 bool cDvbDevice::Initialize(void)
 {
   int found = 0;
-  int i;
+  int i, j, rc = 0;
   for (i = 0; i < MAXDVBDEVICES; i++) {
+    j = 0;
+    while (rc != ENOENT) {
       if (UseDevice(NextCardIndex())) {
-         if (Probe(*cDvbName(DEV_DVB_FRONTEND, i))) {
-            new cDvbDevice(i);
-            found++;
-            }
-         else
-            break;
+         rc = Probe(*cDvbName(DEV_DVB_FRONTEND, i ,j));
+         switch (rc) {
+	    case 0:        dvbDevice[i] = new cDvbDevice(i,j);
+		    	   dvbDevice[i]->SetNumFrontends(j);
+			   dvbDevice[i]->SetCurFrontends(j);
+            		   found++;
+			   break;
+	    case EBUSY:    // we have a frontend that can't work in shared mode
+			   if (dvbDevice[i])
+			      dvbDevice[i]->SetNumFrontends(j);
+			   esyslog("cDvbDevice::Initialize: WARNING %d - Device or resource busy", rc);
+			   // we have a frontend that can't work in shared mode
+			   break;
+	    case ENOENT:   esyslog("cDvbDevice::Initialize: Device %d have %d frontends", i, j);
+			   break;
+            default:       dvbDevice[i] = NULL;
+			   esyslog("cDvbDevice::Initialize: %d", rc);
+			   break;
          }
+      }
       else
          NextCardIndex(1); // skips this one
-      }
+      j++;
+    }
+  }
+
   NextCardIndex(MAXDVBDEVICES - i); // skips the rest
   if (found > 0)
      isyslog("found %d video device%s", found, found > 1 ? "s" : "");
@@ -668,7 +695,8 @@
      memset(&pesFilterParams, 0, sizeof(pesFilterParams));
      if (On) {
         if (Handle->handle < 0) {
-           Handle->handle = DvbOpen(DEV_DVB_DEMUX, CardIndex(), O_RDWR | O_NONBLOCK, true);
+	   esyslog("SetPid: CardIndex=%d", CardIndex());
+           Handle->handle = DvbOpen(DEV_DVB_DEMUX, CardIndex(), dvbDevice[CardIndex()]->GetCurFrontends(), O_RDWR | O_NONBLOCK, true);
            if (Handle->handle < 0) {
               LOG_ERROR;
               return false;
@@ -705,7 +733,7 @@
 
 int cDvbDevice::OpenFilter(u_short Pid, u_char Tid, u_char Mask)
 {
-  const char *FileName = *cDvbName(DEV_DVB_DEMUX, CardIndex());
+  const char *FileName = *cDvbName(DEV_DVB_DEMUX, CardIndex(), dvbDevice[CardIndex()]->GetCurFrontends());
   int f = open(FileName, O_RDWR | O_NONBLOCK);
   if (f >= 0) {
      dmx_sct_filter_params sctFilterParams;
@@ -769,6 +797,31 @@
   bool result = false;
   bool hasPriority = Priority < 0 || Priority > this->Priority();
   bool needsDetachReceivers = false;
+  int frontend = 0, maxfrontend = 0;
+  int adapter;
+
+//Todo: Add test to check if frontend is busy
+
+  adapter = CardIndex();
+
+  maxfrontend = dvbDevice[adapter]->GetNumFrontends();
+
+  while (!result && frontend <= maxfrontend ) {
+
+  esyslog("cDvbDevice::ProvidesChannel: frontend %d, maxfrontend %d, cardIndex %d", frontend, maxfrontend, adapter);
+
+//  if (frontend != 0) {  //wrong - should be frontend != GetCurFrontends(adapter)
+ 
+  if (frontend != dvbDevice[adapter]->GetCurFrontends()) {
+   dvbDevice[adapter]->SetCurFrontends(frontend);
+   ForceCardIndex(adapter);
+    delete dvbDevice[adapter];
+    dvbDevice[adapter] = NULL;
+    esyslog("cDvbDevice::ProvidesChannel stub: stop and restart frontend adapter/frontend %d/%d", adapter, frontend);
+    sleep(2); //dirty hack
+    dvbDevice[adapter] = new cDvbDevice(adapter, frontend);
+   ForceCardIndex(-1);
+  } 
 
   if (ProvidesSource(Channel->Source()) && ProvidesCa(Channel)) {
      result = hasPriority;
@@ -798,6 +851,11 @@
      }
   if (NeedsDetachReceivers)
      *NeedsDetachReceivers = needsDetachReceivers;
+
+  frontend++;
+
+  }
+
   return result;
 }
 
@@ -836,7 +894,18 @@
 
   // Set the tuner:
 
+//  cardindexbkp=CardIndex();
+//  SetNextCardIndex(frontend+1);
+//  delete dvbDevice[CardIndex()];
+//  dvbDevice[i]= NULL;
+//  if (frontend == 0)
+//    frontend = 1;
+//  else
+//    frontend = 0;
+//  esyslog("Allocating new cDvbDevice: Frontend %d, CardIndex %d", frontend, CardIndex());
+//  dvbDevice[CardIndex()] = new cDvbDevice(CardIndex(), frontend);
   dvbTuner->Set(Channel, DoTune);
+//  SetNextCardIndex(cardindexbkp);
 
   // If this channel switch was requested by the EITScanner we don't wait for
   // a lock and don't set any live PIDs (the EITScanner will wait for the lock
@@ -954,8 +1023,8 @@
 {
   if (PlayMode != pmExtern_THIS_SHOULD_BE_AVOIDED && fd_video < 0 && fd_audio < 0) {
      // reopen the devices
-     fd_video = DvbOpen(DEV_DVB_VIDEO,  CardIndex(), O_RDWR | O_NONBLOCK);
-     fd_audio = DvbOpen(DEV_DVB_AUDIO,  CardIndex(), O_RDWR | O_NONBLOCK);
+     fd_video = DvbOpen(DEV_DVB_VIDEO,  CardIndex(), dvbDevice[CardIndex()]->GetCurFrontends(), O_RDWR | O_NONBLOCK);
+     fd_audio = DvbOpen(DEV_DVB_AUDIO,  CardIndex(), dvbDevice[CardIndex()]->GetCurFrontends(), O_RDWR | O_NONBLOCK);
      SetVideoFormat(Setup.VideoFormat);
      }
 
@@ -1183,7 +1252,7 @@
 bool cDvbDevice::OpenDvr(void)
 {
   CloseDvr();
-  fd_dvr = DvbOpen(DEV_DVB_DVR, CardIndex(), O_RDONLY | O_NONBLOCK, true);
+  fd_dvr = DvbOpen(DEV_DVB_DVR, CardIndex(), dvbDevice[CardIndex()]->GetCurFrontends(), O_RDONLY | O_NONBLOCK, true);
   if (fd_dvr >= 0)
      tsBuffer = new cTSBuffer(fd_dvr, MEGABYTE(2), CardIndex() + 1);
   return fd_dvr >= 0;
diff -u -N -r vdr_1.4.5_orig/dvbdevice.h vdr_1.4.5_eddi/dvbdevice.h
--- vdr_1.4.5_orig/dvbdevice.h	2006-05-28 17:05:19.000000000 +0200
+++ vdr_1.4.5_eddi/dvbdevice.h	2007-02-08 00:38:11.000000000 +0100
@@ -20,6 +20,7 @@
 #endif
 
 #define MAXDVBDEVICES  4
+#define MAXDVBFRONTENDS  4
 
 class cDvbTuner;
 
@@ -27,7 +28,7 @@
 
 class cDvbDevice : public cDevice {
 private:
-  static bool Probe(const char *FileName);
+  static int Probe(const char *FileName);
          ///< Probes for existing DVB devices.
 public:
   static bool Initialize(void);
@@ -36,15 +37,20 @@
          ///< \return True if any devices are available.
 private:
   fe_type_t frontendType;
-  int fd_osd, fd_audio, fd_video, fd_dvr, fd_stc;
+  int fd_frontend, fd_osd, fd_audio, fd_video, fd_dvr, fd_stc;
+  int numFrontends, curFrontends;
 protected:
   virtual void MakePrimaryDevice(bool On);
 public:
-  cDvbDevice(int n);
+  cDvbDevice(int adapter, int frontend);
   virtual ~cDvbDevice();
   virtual bool Ready(void);
   virtual int ProvidesCa(const cChannel *Channel) const;
   virtual bool HasDecoder(void) const;
+  void SetNumFrontends(int n) { numFrontends = n; esyslog("SetNumFrontends: %d", numFrontends); }
+  int GetNumFrontends(void) const { esyslog("GetNumFrontends: %d", numFrontends); return numFrontends; }
+  void SetCurFrontends(int n) { curFrontends = n; esyslog("SetCurFrontends: %d", curFrontends); }
+  int GetCurFrontends(void) const { esyslog("GetCurFrontends: %d", curFrontends); return curFrontends; }
 
 // SPU facilities
 
