Index: libs/libmythtv/libmythtv.pro
===================================================================
--- libs/libmythtv/libmythtv.pro	(revision 15017)
+++ libs/libmythtv/libmythtv.pro	(working copy)
@@ -347,10 +347,10 @@
     # Channel stuff
     HEADERS += channelbase.h               dtvchannel.h
     HEADERS += signalmonitor.h             dtvsignalmonitor.h
-    HEADERS += inputinfo.h
+    HEADERS += inputinfo.h                 inputgroupmap.h
     SOURCES += channelbase.cpp             dtvchannel.h
     SOURCES += signalmonitor.cpp           dtvsignalmonitor.cpp
-    SOURCES += inputinfo.cpp
+    SOURCES += inputinfo.cpp               inputgroupmap.cpp
 
     # Channel scanner stuff
     HEADERS += scanwizard.h                scanwizardhelpers.h
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 15017)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -574,6 +574,15 @@
             TunedInputInfo busy_input;
             bool is_busy = RemoteIsBusy(cardids[i], busy_input);
 
+            // if the other recorder is busy, but the input is
+            // not in a shared input group, then as far as we're
+            // concerned here it isn't busy.
+            if (is_busy)
+            {
+                is_busy = (bool) igrp.GetSharedInputGroup(
+                    busy_input.inputid, rcinfo->inputid);
+            }
+
             if (is_busy && !mplexid)
             {
                 mplexid  = (*it).info->GetMplexID();
Index: libs/libmythtv/inputgroupmap.cpp
===================================================================
--- libs/libmythtv/inputgroupmap.cpp	(revision 0)
+++ libs/libmythtv/inputgroupmap.cpp	(revision 0)
@@ -0,0 +1,80 @@
+// -*- Mode: c++ -*-
+/*
+ *   Copyright (c) Daniel Kristjansson 2007
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU General Public License as published by
+ *   the Free Software Foundation; either version 2 of the License, or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU General Public License for more details.
+ *
+ *   You should have received a copy of the GNU General Public License
+ *   along with this program; if not, write to the Free Software
+ *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+#include "inputgroupmap.h"
+#include "mythdbcon.h"
+
+bool InputGroupMap::Build(void)
+{
+    bool ok = true;
+    inputgroupmap.clear();
+    MSqlQuery query(MSqlQuery::InitCon());
+
+    query.prepare("SELECT cardinputid, inputgroupid from inputgroup");
+    if (!query.exec())
+    {
+        MythContext::DBError("InputGroupMap::Build 1", query);
+        ok = false;
+    }
+    else
+    {
+        while (query.next())
+        {
+            uint inputid = query.value(0).toUInt();
+            uint groupid = query.value(1).toUInt();
+            inputgroupmap[inputid].push_back(groupid);
+        }
+    }
+
+    query.prepare("SELECT cardinputid, cardid from cardinput");
+    if (!query.exec())
+    {
+        MythContext::DBError("InputGroupMap::Build 2", query);
+        ok = false;
+    }
+    else
+    {
+        while (query.next())
+        {
+            uint inputid = query.value(0).toUInt();
+            uint groupid = query.value(1).toUInt() + 1000;
+            if (inputgroupmap[inputid].empty())
+                inputgroupmap[inputid].push_back(groupid);
+        }
+    }
+
+    return ok;
+}
+
+uint InputGroupMap::GetSharedInputGroup(uint inputid1, uint inputid2) const
+{
+    const InputGroupList &input1 = inputgroupmap[inputid1];
+    const InputGroupList &input2 = inputgroupmap[inputid2];
+    if (input1.empty() || input2.empty())
+        return 0;
+
+    InputGroupList::const_iterator it;
+    for (it = input1.begin(); it != input1.end(); ++it)
+    {
+        if (find(input2.begin(), input2.end(), *it) != input2.end())
+            return *it;
+    }
+
+    return 0;
+}
Index: libs/libmythtv/tv_rec.h
===================================================================
--- libs/libmythtv/tv_rec.h	(revision 15017)
+++ libs/libmythtv/tv_rec.h	(working copy)
@@ -11,6 +11,7 @@
 #include <qwaitcondition.h>
 
 #include "inputinfo.h"
+#include "inputgroupmap.h"
 #include "mythdeque.h"
 #include "programinfo.h"
 #include "tv.h"
@@ -347,6 +348,7 @@
     int     overRecordSecNrml;
     int     overRecordSecCat;
     QString overRecordCategory;
+    InputGroupMap igrp;
 
     // Configuration variables from setup routines
     int               cardid;
Index: libs/libmythtv/inputgroupmap.h
===================================================================
--- libs/libmythtv/inputgroupmap.h	(revision 0)
+++ libs/libmythtv/inputgroupmap.h	(revision 0)
@@ -0,0 +1,26 @@
+// -*- Mode: c++ -*-
+#ifndef _INPUTGROUPMAP_H_
+#define _INPUTGROUPMAP_H_
+
+// C++ headers
+#include <vector>
+using namespace std;
+
+// Qt headers
+#include <qmap.h>
+
+typedef vector<uint> InputGroupList;
+
+class InputGroupMap
+{
+  public:
+    InputGroupMap() { Build(); }
+
+    bool Build(void);
+    uint GetSharedInputGroup(uint input1, uint input2) const;
+
+  private:
+    QMap<uint, InputGroupList> inputgroupmap;
+};
+
+#endif // _INPUTGROUPMAP_H_
Index: programs/mythbackend/scheduler.h
===================================================================
--- programs/mythbackend/scheduler.h	(revision 15017)
+++ programs/mythbackend/scheduler.h	(working copy)
@@ -16,6 +16,7 @@
 #include "scheduledrecording.h"
 #include "programinfo.h"
 #include "remoteutil.h"
+#include "inputgroupmap.h"
 
 class EncoderLink;
 class MainServer;
@@ -34,8 +35,6 @@
 typedef RecList::const_iterator RecConstIter;
 typedef RecList::iterator RecIter;
 
-typedef vector<int> InputGroupList;
-
 class Scheduler : public QObject
 {
   public:
@@ -130,9 +129,6 @@
     int FillRecordingDir(ProgramInfo *pginfo, RecList& reclist);
     void FillDirectoryInfoCache(bool force = false);
 
-    void BuildInputGroupMap(void);
-    int  GetSharedInputGroup(int, int) const;
-
     QValueList<int> reschedQueue;
     QMutex reschedLock;
     QMutex recordmatchLock;
@@ -143,7 +139,7 @@
     QMap<int, RecList> cardlistmap;
     QMap<int, RecList> recordidlistmap;
     QMap<QString, RecList> titlelistmap;
-    QMap<int, InputGroupList> inputgroupmap;
+    InputGroupMap igrp;
 
     QMutex *reclist_lock;
     bool reclist_changed;
Index: programs/mythbackend/scheduler.cpp
===================================================================
--- programs/mythbackend/scheduler.cpp	(revision 15018)
+++ programs/mythbackend/scheduler.cpp	(working copy)
@@ -300,8 +300,6 @@
     schedMoveHigher = (bool)gContext->GetNumSetting("SchedMoveHigher");
     schedTime = QDateTime::currentDateTime();
 
-    BuildInputGroupMap();
-
     VERBOSE(VB_SCHEDULE, "BuildWorkList...");
     BuildWorkList();
     VERBOSE(VB_SCHEDULE, "AddNewRecords...");
@@ -815,7 +813,7 @@
             cout << QString("\n  comparing with '%1' ").arg(q->title);
 
         if (p->cardid != 0 && (p->cardid != q->cardid) &&
-            !GetSharedInputGroup(p->inputid, q->inputid))
+            !igrp.GetSharedInputGroup(p->inputid, q->inputid))
         {
             if (is_conflict_dbg)
                 cout << "  cardid== ";
@@ -845,14 +843,14 @@
             cout << "\n" <<
                 QString("  cardid's: %1, %2 ").arg(p->cardid).arg(q->cardid) +
                 QString("Shared input group: %1 ")
-                .arg(GetSharedInputGroup(p->inputid, q->inputid)) +
+                .arg(igrp.GetSharedInputGroup(p->inputid, q->inputid)) +
                 QString("mplexid's: %1, %2")
                 .arg(p->GetMplexID()).arg(q->GetMplexID());
 
         // if two inputs are in the same input group we have a conflict
         // unless the programs are on the same multiplex.
         if (p->cardid && (p->cardid != q->cardid) &&
-            GetSharedInputGroup(p->inputid, q->inputid) &&
+            igrp.GetSharedInputGroup(p->inputid, q->inputid) &&
             p->GetMplexID() && (p->GetMplexID() == q->GetMplexID()))
         {
             continue;
@@ -3365,60 +3363,6 @@
     fsInfoCacheFillTime = QDateTime::currentDateTime();
 }
 
-void Scheduler::BuildInputGroupMap(void)
-{
-    inputgroupmap.clear();
-    MSqlQuery query(dbConn);
-
-    query.prepare("SELECT cardinputid, inputgroupid from inputgroup");
-    if (!query.exec())
-    {
-        MythContext::DBError("BuildInputGroupMap 1", query);
-    }
-    else
-    {
-        while (query.next())
-        {
-            int inputid = query.value(0).toUInt();
-            int groupid = query.value(1).toUInt();
-            inputgroupmap[inputid].push_back(groupid);
-        }
-    }
-
-    query.prepare("SELECT cardinputid, cardid from cardinput");
-    if (!query.exec())
-    {
-        MythContext::DBError("BuildInputGroupMap 2", query);
-    }
-    else
-    {
-        while (query.next())
-        {
-            int inputid = query.value(0).toUInt();
-            int groupid = query.value(1).toUInt() + 1000;
-            if (inputgroupmap[inputid].empty())
-                inputgroupmap[inputid].push_back(groupid);
-        }
-    }
-}
-
-int Scheduler::GetSharedInputGroup(int inputid1, int inputid2) const
-{
-    const InputGroupList &input1 = inputgroupmap[inputid1];
-    const InputGroupList &input2 = inputgroupmap[inputid2];
-    if (input1.empty() || input2.empty())
-        return 0;
-
-    InputGroupList::const_iterator it;
-    for (it = input1.begin(); it != input1.end(); ++it)
-    {
-        if (find(input2.begin(), input2.end(), *it) != input2.end())
-            return *it;
-    }
-
-    return 0;
-}
-
 void Scheduler::SchedPreserveLiveTV(void)
 {
     if (!livetvTime.isValid())
