diff --git a/device.c b/device.c
index 4b9c9cc7..1c1b4d28 100644
--- a/device.c
+++ b/device.c
@@ -249,6 +249,57 @@ cDevice *cDevice::GetDevice(const cChannel *Channel, int Priority, bool LiveView
 {
   // Collect the current priorities of all CAM slots that can decrypt the channel:
   int NumCamSlots = CamSlots.Count();
+  if (!NumCamSlots) {
+     bool NeedsDetachReceivers = false;
+     const bool InternalCamNeeded = Channel->Ca() >= CA_ENCRYPTED_MIN;
+     cDevice *d = NULL;
+     uint32_t Impact = 0xFFFFFFFF; // we're looking for a device with the least impact
+     for (int i = 0; i < numDevices; i++) {
+         if (Channel->Ca() && Channel->Ca() <= CA_DVB_MAX && Channel->Ca() != device[i]->DeviceNumber() + 1)
+            continue; // a specific card was requested, but not this one
+         const bool HasInternalCam = device[i]->HasInternalCam();
+         if (InternalCamNeeded && !HasInternalCam)
+            continue; // no CAM is able to decrypt this channel and the device uses vdr handled CAMs
+         bool ndr;
+         if (device[i]->ProvidesChannel(Channel, Priority, &ndr)) { // this device is basically able to do the job
+            // Put together an integer number that reflects the "impact" using
+            // this device would have on the overall system. Each condition is represented
+            // by one bit in the number (or several bits, if the condition is actually
+            // a numeric value). The sequence in which the conditions are listed corresponds
+            // to their individual severity, where the one listed first will make the most
+            // difference, because it results in the most significant bit of the result.
+            uint32_t imp = 0;
+            imp <<= 1;
+            imp <<= 1; imp |= LiveView && (!device[i]->IsPrimaryDevice() || ndr);                                  // prefer the primary device for live viewing if we don't need to detach existing receivers
+            imp <<= 1; imp |= !device[i]->Receiving() && (device[i] != cTransferControl::ReceiverDevice() || device[i]->IsPrimaryDevice()) || ndr; // use receiving devices if we don't need to detach existing receivers, but avoid primary device in local transfer mode
+            imp <<= 1; imp |= device[i]->Receiving();                                                               // avoid devices that are receiving
+            imp <<= 5; imp |= GetClippedNumProvidedSystems(5, device[i]) - 1;                                       // avoid cards which support multiple delivery systems
+            imp <<= 1; imp |= device[i] == cTransferControl::ReceiverDevice();                                      // avoid the Transfer Mode receiver device
+            imp <<= 8; imp |= device[i]->Priority() - IDLEPRIORITY;                                                 // use the device with the lowest priority (- IDLEPRIORITY to assure that values -100..99 can be used)
+            imp <<= 8;
+            imp <<= 1; imp |= ndr;                                                                                  // avoid devices if we need to detach existing receivers
+            imp <<= 1; imp |= !InternalCamNeeded && device[i]->HasCi();                       // avoid cards with Common Interface for FTA channels
+            imp <<= 1; imp |= device[i]->AvoidRecording();                                                          // avoid SD full featured cards
+            imp <<= 1;
+            imp <<= 1; imp |= device[i]->IsPrimaryDevice();                                                         // avoid the primary device
+            if (imp < Impact) {
+               // This device has less impact than any previous one, so we take it.
+               Impact = imp;
+               d = device[i];
+               NeedsDetachReceivers = ndr;
+               }
+            }
+         }
+
+     if (d) {
+        if (!Query && NeedsDetachReceivers)
+           d->DetachAllReceivers();
+        if (d->CamSlot() && !d->CamSlot()->IsDecrypting())
+           d->CamSlot()->Assign(NULL);
+        }
+     return d;
+     }
+
   int SlotPriority[NumCamSlots];
   int NumUsableSlots = 0;
   bool InternalCamNeeded = false;
