Index: libs/libmythtv/previouslist.cpp
===================================================================
--- libs/libmythtv/previouslist.cpp	(revision 10303)
+++ libs/libmythtv/previouslist.cpp	(working copy)
@@ -40,7 +40,6 @@
     hourFormat = gContext->GetSetting("TimeFormat");
     timeFormat = gContext->GetSetting("ShortDateFormat") + " " + hourFormat;
     fullDateFormat = dayFormat + " " + hourFormat;
-    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum + 0");
     channelFormat = gContext->GetSetting("ChannelFormat", "<num> <sign>");
 
     allowEvents = true;
Index: libs/libmythtv/channelutil.h
===================================================================
--- libs/libmythtv/channelutil.h	(revision 10303)
+++ libs/libmythtv/channelutil.h	(working copy)
@@ -8,6 +8,33 @@
 
 class NetworkInformationTable;
 
+class DBChannel
+{
+  public:
+    DBChannel(const QString &_channum, const QString &_callsign,
+              uint _chanid, uint _major_chan, uint _minor_chan,
+              uint _favorite,
+              const QString &_name, const QString &_icon) :
+        channum(_channum), callsign(_callsign), chanid(_chanid),
+        major_chan(_major_chan), minor_chan(_minor_chan),
+        favorite(_favorite),
+        name(_name), icon(_icon) {}
+
+    bool operator == (uint _chanid) const
+        { return chanid == _chanid; }
+
+    QString channum;
+    QString callsign;
+    uint    chanid;
+    uint    major_chan;
+    uint    minor_chan;
+    uint    favorite;
+    QString name;
+    QString icon;
+};
+typedef vector<DBChannel> DBChanList;
+
+
 /** \class ChannelUtil
  *  \brief Collection of helper utilities for channel DB use
  */
@@ -44,9 +71,17 @@
     static int     GetBetterMplexID(int current_mplexid,
                                     int transport_id, int network_id);
 
-    static int     GetTuningParams(int mplexid, QString &modulation);
+    static bool    GetTuningParams(uint mplexid,
+                                   QString  &modulation,
+                                   uint64_t &frequency,
+                                   uint     &dvb_transportid,
+                                   uint     &dvb_networkid);
+
     static bool    GetATSCChannel(uint sourceid, const QString &channum,
                                   uint &major,   uint          &minor);
+    static bool    IsATSCChannel(uint sourceid, const QString &channum)
+        { uint m1, m2; GetATSCChannel(sourceid, channum, m1,m2); return m2; }
+
     // Channel/Service Stuff
     static int     CreateChanID(uint sourceid, const QString &chan_num);
 
@@ -90,31 +125,26 @@
 
     static int     GetChanID(uint sourceid, const QString &channum)
         { return GetChannelValueInt("chanid", sourceid, channum); }
-    static int     GetATSCSRCID(uint sourceid, const QString &channum)
-        { return GetChannelValueInt("atscsrcid", sourceid, channum); }
+    static bool    GetChannelData(
+        uint    sourceid,         const QString &channum,
+        QString &tvformat,        QString       &modulation,
+        QString &freqtable,       QString       &freqid,
+        int     &finetune,        uint64_t      &frequency,
+        int     &mpeg_prog_num,
+        uint    &atsc_major,      uint          &atsc_minor,
+        uint    &dvb_transportid, uint          &dvb_networkid,
+        uint    &mplexid,         bool          &commfree);
+    static uint    GetSourceID(uint cardid, const QString &inputname);
     static int     GetProgramNumber(uint sourceid, const QString &channum)
         { return GetChannelValueInt("serviceid", sourceid, channum); }
     static QString GetVideoFilters(uint sourceid, const QString &channum)
         { return GetChannelValueStr("videofilters", sourceid, channum); }
 
-    static QString GetNextChannel(uint           cardid,
-                                  const QString &inputname,
-                                  const QString &channum,
-                                  int            direction,
-                                  QString       &channelorder,
-                                  uint          &chanid);
+    static DBChanList GetChannels(uint srcid, bool vis_only, QString grp="");
+    static void    SortChannels(DBChanList &list, const QString &order);
 
-    static uint    GetNextChannel(uint           cardid,
-                                  const QString &inputname,
-                                  const QString &channum,
-                                  int            direction,
-                                  QString       &channelorder)
-    {
-        uint chanid = 0;
-        GetNextChannel(cardid,    inputname,    channum,
-                       direction, channelorder, chanid);
-        return chanid;
-    }
+    static uint    GetNextChannel(const DBChanList &sorted,
+                                  uint old_chanid, int direction);
 
     static QString GetChannelValueStr(const QString &channel_field,
                                       uint           sourceid,
Index: libs/libmythtv/proglist.cpp
===================================================================
--- libs/libmythtv/proglist.cpp	(revision 10303)
+++ libs/libmythtv/proglist.cpp	(working copy)
@@ -23,6 +23,7 @@
 #include "mythcontext.h"
 #include "remoteutil.h"
 #include "mythdbcon.h"
+#include "channelutil.h"
 
 ProgLister::ProgLister(ProgListType pltype,
                        const QString &view, const QString &from,
@@ -39,7 +40,7 @@
     hourFormat = gContext->GetSetting("TimeFormat");
     timeFormat = gContext->GetSetting("ShortDateFormat") + " " + hourFormat;
     fullDateFormat = dayFormat + " " + hourFormat;
-    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum + 0");
+    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum");
     channelFormat = gContext->GetSetting("ChannelFormat", "<num> <sign>");
 
     switch (pltype)
@@ -977,36 +978,26 @@
     stationList.clear();
     stationList << "";
 
-    query.prepare(QString("SELECT channel.chanid, channel.channum, "
-                  "channel.callsign, channel.name FROM channel "
-                  "WHERE channel.visible = 1 "
-                  "GROUP BY callsign "
-                  "ORDER BY ") + channelOrdering + ";");
-    query.exec();
+    DBChanList channels = ChannelUtil::GetChannels(0, false, "callsign");
+    ChannelUtil::SortChannels(channels, channelOrdering);
 
-    if (query.isActive() && query.size())
+    for (uint i = 0; i < channels.size(); i++)
     {
-        while (query.next())
-        {
-            QString chanid = query.value(0).toString();
-            QString channum = query.value(1).toString();
-            QString chansign = QString::fromUtf8(query.value(2).toString());
-            QString channame = QString::fromUtf8(query.value(3).toString());
+        QString chantext = QDeepCopy<QString>(channelFormat);
+        chantext
+            .replace("<num>",  channels[i].channum)
+            .replace("<sign>", channels[i].callsign)
+            .replace("<name>", channels[i].name);
 
-            QString chantext = channelFormat;
-            chantext.replace("<num>", channum)
-                .replace("<sign>", chansign)
-                .replace("<name>", channame);
+        viewList << QString::number(channels[i].chanid);
+        viewTextList << chantext;
 
-            viewList << chanid;
-            viewTextList << chantext;
-
-            powerStation->insertItem(chantext);
-            stationList << chansign;
-            if (chansign == field[5])
-                powerStation->setCurrentItem(powerStation->count() - 1);
-        }
+        powerStation->insertItem(chantext);
+        stationList << channels[i].callsign;
+        if (channels[i].callsign == field[5])
+            powerStation->setCurrentItem(powerStation->count() - 1);
     }
+
     powerPopup->addWidget(powerStation);
 
     powerOkButton = new MythPushButton(powerPopup);
@@ -1185,33 +1176,22 @@
 
     if (type == plChannel) // list by channel
     {
-        MSqlQuery query(MSqlQuery::InitCon()); 
-        query.prepare(QString("SELECT channel.chanid, channel.channum, "
-                      "channel.callsign, channel.name FROM channel "
-                      "WHERE channel.visible = 1 "
-                      "GROUP BY channum, callsign "
-                      "ORDER BY ") + channelOrdering + ";");
-        query.exec();
+        DBChanList channels = ChannelUtil::GetChannels(0, false, "callsign");
+        ChannelUtil::SortChannels(channels, channelOrdering);
 
-        if (query.isActive() && query.size())
+        for (uint i = 0; i < channels.size(); i++)
         {
-            while (query.next())
-            {
-                QString chanid = query.value(0).toString();
-                QString channum = query.value(1).toString();
-                QString chansign = QString::fromUtf8(query.value(2).toString());
-                QString channame = QString::fromUtf8(query.value(3).toString());
+            QString chantext = QDeepCopy<QString>(channelFormat);
+            chantext
+                .replace("<num>",  channels[i].channum)
+                .replace("<sign>", channels[i].callsign)
+                .replace("<name>", channels[i].name);
 
-                QString chantext = channelFormat;
-                chantext.replace("<num>", channum)
-                    .replace("<sign>", chansign)
-                    .replace("<name>", channame);
-
-                viewList << chanid;
-                viewTextList << chantext;
-            }
+            viewList << QString::number(channels[i].chanid);
+            viewTextList << chantext;
         }
-        if (view != "")
+
+        if (!view.isEmpty())
             curView = viewList.findIndex(view);
     }
     else if (type == plCategory) // list by category
Index: libs/libmythtv/guidegrid.cpp
===================================================================
--- libs/libmythtv/guidegrid.cpp	(revision 10303)
+++ libs/libmythtv/guidegrid.cpp	(working copy)
@@ -31,6 +31,7 @@
 #include "customedit.h"
 #include "util.h"
 #include "remoteutil.h"
+#include "channelutil.h"
 
 bool RunProgramGuide(uint &chanid, QString &channum,
                      bool thread, TV *player,
@@ -179,7 +180,7 @@
             container->SetDrawFontShadow(false);
     }
 
-    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum + 0");
+    channelOrdering = gContext->GetSetting("ChannelOrdering", "channum");
     dateformat = gContext->GetSetting("ShortDateFormat", "ddd d");
     unknownTitle = gContext->GetSetting("UnknownTitle", "Unknown");
     unknownCategory = gContext->GetSetting("UnknownCategory", "Unknown");
@@ -559,69 +560,34 @@
 
 void GuideGrid::fillChannelInfos(bool gotostartchannel)
 {
-    MSqlQuery query(MSqlQuery::InitCon());
-
     m_channelInfos.clear();
 
+    DBChanList channels = ChannelUtil::GetChannels(0, true, "callsign");
+    ChannelUtil::SortChannels(channels, channelOrdering);
+
     if (showFavorites)
     {
-        query.prepare(
-            "SELECT channel.channum, channel.callsign, "
-            "       channel.icon,    channel.chanid, "
-            "       favorites.favid, channel.name "
-            "FROM videosource, cardinput, favorites, channel "
-            "WHERE channel.chanid       = favorites.chanid     AND "
-            "      visible              = 1                    AND "
-            "      channel.sourceid     = videosource.sourceid AND "
-            "      videosource.sourceid = cardinput.sourceid "
-            "GROUP BY channum, callsign "
-            "ORDER BY " + channelOrdering);
-
-        if (query.exec() && query.isActive())
-            showFavorites = query.size();
-        else
-            MythContext::DBError("fillChannelInfos -- favorites", query);
-    }
-
-    if (!showFavorites)
-    {
-        query.prepare(
-            "SELECT channel.channum, channel.callsign, "
-            "       channel.icon,    channel.chanid, "
-            "       favorites.favid, channel.name "
-            "FROM videosource, cardinput, "
-            "       channel LEFT JOIN favorites "
-            "       ON favorites.chanid = channel.chanid "
-            "WHERE visible              = 1                    AND "
-            "      channel.sourceid     = videosource.sourceid AND "
-            "      videosource.sourceid = cardinput.sourceid "
-            "GROUP BY channum, callsign "
-            "ORDER BY " + channelOrdering);
-
-        if (!query.exec() || !query.isActive())
+        DBChanList tmp;
+        for (uint i = 0; i < channels.size(); i++)
         {
-            MythContext::DBError("fillChannelInfos -- all connected", query);
-            return;
+            if (channels[i].favorite)
+                tmp.push_back(channels[i]);
         }
+
+        if (!tmp.empty())
+            channels = tmp;
     }
- 
+
     bool startingset = false;
-    while (query.next())
+    for (uint i = 0; i < channels.size(); i++)
     {
         ChannelInfo val;
-
-        val.chanstr  = query.value(0).toString();
-        val.chanid   = query.value(3).toInt();
-
-        // validate the channum and chanid, skip channel if these are invalid
-        if (val.chanstr == "" || !val.chanid)
-            continue;
-
-        // fill in the rest of the data...
-        val.callsign = QString::fromUtf8(query.value(1).toString());
-        val.iconpath = query.value(2).toString();
-        val.favid    = query.value(4).toInt();
-        val.channame = QString::fromUtf8(query.value(5).toString());
+        val.chanstr  = channels[i].channum;
+        val.chanid   = channels[i].chanid;
+        val.callsign = channels[i].callsign;
+        val.favid    = channels[i].favorite;
+        val.channame = channels[i].name;
+        val.iconpath = channels[i].icon;
         val.iconload = false;
 
         // set starting channel index if it hasn't been set
@@ -633,10 +599,11 @@
             m_currentStartChannel = m_channelInfos.size();
             startingset = true;
         }
-                
+
         // add the new channel to the list
         m_channelInfos.push_back(val);
     }
+ 
     // set starting channel index to 0 if it hasn't been set
     if (gotostartchannel)
         m_currentStartChannel = (startingset) ? m_currentStartChannel : 0;
Index: libs/libmythtv/dbcheck.cpp
===================================================================
--- libs/libmythtv/dbcheck.cpp	(revision 10303)
+++ libs/libmythtv/dbcheck.cpp	(working copy)
@@ -10,7 +10,7 @@
 #include "mythdbcon.h"
 
 /// This is the DB schema version expected by the running MythTV instance.
-const QString currentDatabaseVersion = "1146";
+const QString currentDatabaseVersion = "1147";
 
 static bool UpdateDBVersionNumber(const QString &newnumber);
 static bool performActualUpdate(const QString updates[], QString version,
@@ -276,7 +276,7 @@
 update the listings. Using the on-air-guide is currently experimental
 and must be selected when you compile %MythTV. Finally, the 'atscsrcid'
 field currently contains both the major and minor atsc channels, encoded
-in the form (majorChannel * 256 | minorChannel) when using DVB drivers.
+in the form (atsc_major_chan * 256 | atsc_minor_chan).
 
 \section program_table Program Entry Table (program)
 'category_type' holds one of these exact four strings:
@@ -2315,9 +2315,25 @@
             return false;
     }
 
+    if (dbver == "1146")
+    {
+        const QString updates[] = {
+"ALTER TABLE channel ADD atsc_major_chan INT UNSIGNED NOT NULL default '0';",
+"ALTER TABLE channel ADD atsc_minor_chan INT UNSIGNED NOT NULL default '0';",
+"UPDATE channel SET atsc_major_chan = atscsrcid / 256;",
+"UPDATE channel SET atsc_minor_chan = atscsrcid % 256;",
+"UPDATE settings SET data='channum' WHERE value='ChannelOrdering' AND data!='callsign';",
+""
+};
+
+        if (!performActualUpdate(updates, "1147", dbver))
+            return false;
+    }
+
 //"ALTER TABLE capturecard DROP COLUMN dvb_recordts;" in 0.21
 //"ALTER TABLE capturecard DROP COLUMN dvb_hw_decoder;" in 0.21
-//"ALTER TABLE cardinput DROP COLUMN  preference;" in 0.22
+//"ALTER TABLE cardinput DROP COLUMN preference;" in 0.22
+//"ALTER TABLE channel DROP COLUMN atscsrcid;" in 0.22
 
     return true;
 }
Index: libs/libmythtv/eithelper.cpp
===================================================================
--- libs/libmythtv/eithelper.cpp	(revision 10303)
+++ libs/libmythtv/eithelper.cpp	(working copy)
@@ -17,9 +17,10 @@
 
 const uint EITHelper::kChunkSize = 20;
 
-static int get_chan_id_from_db(uint sourceid,  uint atscsrcid);
-static int get_chan_id_from_db(uint sourceid,  uint serviceid,
-                               uint networkid, uint transportid);
+static uint get_chan_id_from_db(uint sourceid,
+                                uint atscmajor, uint atscminor);
+static uint get_chan_id_from_db(uint sourceid,  uint serviceid,
+                                uint networkid, uint transportid);
 static void init_fixup(QMap<uint64_t,uint> &fix);
 static int calc_eit_utc_offset(void);
 
@@ -109,10 +110,11 @@
     return insertCount;
 }
 
-void EITHelper::SetFixup(uint atscsrcid, uint eitfixup)
+void EITHelper::SetFixup(uint atsc_major, uint atsc_minor, uint eitfixup)
 {
     QMutexLocker locker(&eitList_lock);
-    fixup[atscsrcid] = eitfixup;
+    uint atsc_key = (atsc_major << 16) | atsc_minor;
+    fixup[atsc_key] = eitfixup;
 }
 
 void EITHelper::SetLanguagePreferences(const QStringList &langPref)
@@ -138,10 +140,12 @@
     sourceid = _sourceid;
 }
 
-void EITHelper::AddEIT(uint atscsrcid, const EventInformationTable *eit)
+void EITHelper::AddEIT(uint atsc_major, uint atsc_minor,
+                       const EventInformationTable *eit)
 {
-    EventIDToATSCEvent &events = incomplete_events[atscsrcid];
-    EventIDToETT &etts = unmatched_etts[atscsrcid];
+    uint atsc_key = (atsc_major << 16) | atsc_minor;
+    EventIDToATSCEvent &events = incomplete_events[atsc_key];
+    EventIDToETT &etts = unmatched_etts[atsc_key];
 
     for (uint i = 0; i < eit->EventCount(); i++)
     {
@@ -154,12 +158,12 @@
 
         if (it != etts.end())
         {
-            CompleteEvent(atscsrcid, ev, *it);
+            CompleteEvent(atsc_major, atsc_minor, ev, *it);
             etts.erase(it);
         }
         else if (!ev.etm)
         {
-            CompleteEvent(atscsrcid, ev, QString::null);
+            CompleteEvent(atsc_major, atsc_minor, ev, QString::null);
         }
         else
         {
@@ -171,26 +175,32 @@
     }
 }
 
-void EITHelper::AddETT(uint atscsrcid, const ExtendedTextTable *ett)
+void EITHelper::AddETT(uint atsc_major, uint atsc_minor,
+                       const ExtendedTextTable *ett)
 {
+    uint atsc_key = (atsc_major << 16) | atsc_minor;
     // Try to complete an Event
-    ATSCSRCToEvents::iterator eits_it = incomplete_events.find(atscsrcid);
+    ATSCSRCToEvents::iterator eits_it = incomplete_events.find(atsc_key);
     if (eits_it != incomplete_events.end())
     {
         EventIDToATSCEvent::iterator it = (*eits_it).find(ett->EventID());
         if (it != (*eits_it).end())
         {
-            CompleteEvent(atscsrcid, *it, ett->ExtendedTextMessage()
-                          .GetBestMatch(languagePreferences));
+            CompleteEvent(
+                atsc_major, atsc_minor, *it,
+                ett->ExtendedTextMessage().GetBestMatch(languagePreferences));
+
             if ((*it).desc)
                 delete [] (*it).desc;
+
             (*eits_it).erase(it);
+
             return;
         }
     }
 
     // Couldn't find matching EIT. If not yet in unmatched ETT map, insert it.
-    EventIDToETT &elist = unmatched_etts[atscsrcid];
+    EventIDToETT &elist = unmatched_etts[atsc_key];
     if (elist.find(ett->EventID()) == elist.end())
     {
         elist[ett->EventID()] = ett->ExtendedTextMessage()
@@ -345,11 +355,11 @@
 // private methods and functions below this line                    //
 //////////////////////////////////////////////////////////////////////
 
-void EITHelper::CompleteEvent(uint atscsrcid,
+void EITHelper::CompleteEvent(uint atsc_major, uint atsc_minor,
                               const ATSCEvent &event,
                               const QString   &ett)
 {
-    uint chanid = GetChanID(atscsrcid);
+    uint chanid = GetChanID(atsc_major, atsc_minor);
     if (!chanid)
         return;
 
@@ -363,25 +373,31 @@
     bool captioned = MPEGDescriptor::Find(list, DescriptorID::caption_service);
     bool stereo = false;
 
+    uint atsc_key = (atsc_major << 16) | atsc_minor;
+
     QMutexLocker locker(&eitList_lock);
     db_events.enqueue(new DBEvent(chanid, QDeepCopy<QString>(event.title),
                                   QDeepCopy<QString>(ett),
                                   starttime, endtime,
-                                  fixup[atscsrcid], captioned, stereo));
+                                  fixup[atsc_key], captioned, stereo));
 }
 
-uint EITHelper::GetChanID(uint atscsrcid)
+uint EITHelper::GetChanID(uint atsc_major, uint atsc_minor)
 {
-    uint key = sourceid << 16 | atscsrcid;
+    uint64_t key;
+    key  = ((uint64_t) sourceid);
+    key |= ((uint64_t) atsc_minor) << 16;
+    key |= ((uint64_t) atsc_major) << 32;
+
     ServiceToChanID::const_iterator it = srv_to_chanid.find(key);
     if (it != srv_to_chanid.end())
         return max(*it, 0);
 
-    int chanid = get_chan_id_from_db(sourceid, atscsrcid);
-    if (chanid != 0)
+    uint chanid = get_chan_id_from_db(sourceid, atsc_major, atsc_minor);
+    if (chanid)
         srv_to_chanid[key] = chanid;
 
-    return max(chanid, 0);
+    return chanid;
 }
 
 uint EITHelper::GetChanID(uint serviceid, uint networkid, uint tsid)
@@ -396,22 +412,25 @@
     if (it != srv_to_chanid.end())
         return max(*it, 0);
 
-    int chanid = get_chan_id_from_db(sourceid, serviceid, networkid, tsid);
-    if (chanid != 0)
+    uint chanid = get_chan_id_from_db(sourceid, serviceid, networkid, tsid);
+    if (chanid)
         srv_to_chanid[key] = chanid;
 
-    return max(chanid, 0);
+    return chanid;
 }
 
-static int get_chan_id_from_db(uint sourceid, uint atscsrcid)
+static uint get_chan_id_from_db(uint sourceid,
+                                uint atsc_major, uint atsc_minor)
 {
     MSqlQuery query(MSqlQuery::InitCon());
     query.prepare(
             "SELECT chanid, useonairguide "
             "FROM channel "
-            "WHERE atscsrcid = :ATSCSRCID AND "
-            "      sourceid  = :SOURCEID");
-    query.bindValue(":ATSCSRCID", atscsrcid);
+            "WHERE atsc_major_chan = :MAJORCHAN AND "
+            "      atsc_minor_chan = :MINORCHAN AND "
+            "      sourceid        = :SOURCEID");
+    query.bindValue(":MAJORCHAN", atsc_major);
+    query.bindValue(":MINORCHAN", atsc_minor);
     query.bindValue(":SOURCEID",  sourceid);
 
     if (!query.exec() || !query.isActive())
@@ -419,15 +438,15 @@
     else if (query.next())
     {
         bool useOnAirGuide = query.value(1).toBool();
-        return (useOnAirGuide) ? query.value(0).toInt() : -1;
+        return (useOnAirGuide) ? query.value(0).toUInt() : 0;
     }
 
-    return -1;
+    return 0;
 }
 
 // Figure out the chanid for this channel
-static int get_chan_id_from_db(uint sourceid, uint serviceid,
-                               uint networkid, uint transportid)
+static uint get_chan_id_from_db(uint sourceid, uint serviceid,
+                                uint networkid, uint transportid)
 {
     MSqlQuery query(MSqlQuery::InitCon());
 
@@ -457,10 +476,10 @@
     {
         // Check to see if we are interseted in this channel
         bool useOnAirGuide = query.value(1).toBool();
-        return (useOnAirGuide) ? query.value(0).toInt() : -1;        
+        return (useOnAirGuide) ? query.value(0).toUInt() : 0;
     }
 
-    return -1;
+    return 0;
 }
 
 static void init_fixup(QMap<uint64_t,uint> &fix)
Index: libs/libmythtv/channelbase.h
===================================================================
--- libs/libmythtv/channelbase.h	(revision 10303)
+++ libs/libmythtv/channelbase.h	(working copy)
@@ -10,7 +10,7 @@
 #include <qsqldatabase.h>
 
 // MythTV headers
-
+#include "channelutil.h"
 #include "frequencies.h"
 #include "tv.h"
 
@@ -31,10 +31,12 @@
 
     InputBase(QString _name,            QString _startChanNum,
               QString _tuneToChannel,   QString _externalChanger,
-              uint    _sourceid,        uint    _cardid) :
+              uint    _sourceid,        uint    _cardid,
+              const DBChanList &_channels) :
         name(_name),                    startChanNum(_startChanNum),
         tuneToChannel(_tuneToChannel),  externalChanger(_externalChanger),
         sourceid(_sourceid),            cardid(_cardid),
+        channels(_channels),
         inputNumV4L(-1),
         videoModeV4L1(0),               videoModeV4L2(0) {}
 
@@ -47,6 +49,7 @@
     QString externalChanger; // for using a cable box...
     uint    sourceid;        // associated channel listings source
     uint    cardid;          // input card id
+    DBChanList channels;
     int     inputNumV4L;
     int     videoModeV4L1;
     int     videoModeV4L2;
@@ -83,6 +86,8 @@
     virtual int GetFd(void) const { return -1; };
 
     // Gets
+    virtual uint GetNextChannel(uint chanid, int direction) const;
+    virtual uint GetNextChannel(const QString &channum, int direction) const;
     virtual int GetInputByName(const QString &input) const;
     virtual QString GetInputByNum(int capchannel) const;
     virtual QString GetCurrentName(void) const
@@ -101,8 +106,6 @@
         { return inputs[GetCurrentInputNum()]->sourceid; }
     virtual uint GetInputCardID(int inputNum) const;
     virtual QStringList GetConnectedInputs(void) const;
-    virtual QString GetOrdering(void) const
-        { return channelorder; }
     /// \brief Returns true iff commercial detection is not required
     //         on current channel, for BBC, CBC, etc.
     bool IsCommercialFree(void) const { return commfree; }
@@ -110,8 +113,6 @@
     virtual QString GetDevice(void) const { return ""; }
 
     // Sets
-    virtual void SetChannelOrdering(const QString &chanorder)
-        { channelorder = chanorder; }
     virtual void Renumber(uint srcid, const QString &oldChanNum,
                           const QString &newChanNum);
 
@@ -148,17 +149,17 @@
     /// \brief Returns program number in PAT, -1 if unknown.
     virtual int GetProgramNumber(void) const
         { return currentProgramNum; };
-    /// \brief Returns major channel, -1 if unknown.
-    virtual int GetMajorChannel(void) const
+    /// \brief Returns major channel, 0 if unknown.
+    virtual uint GetMajorChannel(void) const
         { return currentATSCMajorChannel; };
-    /// \brief Returns minor channel, -1 if unknown.
-    virtual int GetMinorChannel(void) const
+    /// \brief Returns minor channel, 0 if unknown.
+    virtual uint GetMinorChannel(void) const
         { return currentATSCMinorChannel; };
-    /// \brief Returns DVB original_network_id, -1 if unknown.
-    virtual int GetOriginalNetworkID(void) const
+    /// \brief Returns DVB original_network_id, 0 if unknown.
+    virtual uint GetOriginalNetworkID(void) const
         { return currentOriginalNetworkID; };
-    /// \brief Returns DVB transport_stream_id, -1 if unknown.
-    virtual int GetTransportID(void) const
+    /// \brief Returns DVB transport_stream_id, 0 if unknown.
+    virtual uint GetTransportID(void) const
         { return currentTransportID; };
 
     // \brief Set cardid for scanning
@@ -177,18 +178,17 @@
     static void StoreInputChannels(const InputMap&);
 
     TVRec   *pParent;
-    QString  channelorder;
     QString  curchannelname;
     int      currentInputID;
     bool     commfree;
     uint     cardid;
     InputMap inputs;
 
-    int     currentATSCMajorChannel;
-    int     currentATSCMinorChannel;
     int     currentProgramNum;
-    int     currentOriginalNetworkID;
-    int     currentTransportID;
+    uint    currentATSCMajorChannel;
+    uint    currentATSCMinorChannel;
+    uint    currentTransportID;
+    uint    currentOriginalNetworkID;
 };
 
 #endif
Index: libs/libmythtv/previouslist.h
===================================================================
--- libs/libmythtv/previouslist.h	(revision 10303)
+++ libs/libmythtv/previouslist.h	(working copy)
@@ -48,7 +48,6 @@
     QString hourFormat;
     QString timeFormat;
     QString fullDateFormat;
-    QString channelOrdering;
     QString channelFormat;
 
     RecSearchType searchtype;
Index: libs/libmythtv/hdhrchannel.cpp
===================================================================
--- libs/libmythtv/hdhrchannel.cpp	(revision 10303)
+++ libs/libmythtv/hdhrchannel.cpp	(working copy)
@@ -308,20 +308,21 @@
 
 bool HDHRChannel::SetChannelByString(const QString &channum)
 {
-    VERBOSE(VB_CHANNEL, LOC + QString("Set channel '%1'").arg(channum));
+    QString loc = LOC + QString("SetChannelByString(%1)").arg(channum);
+    VERBOSE(VB_CHANNEL, loc);
+    
     if (!Open())
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Set channel request without active connection");
+        VERBOSE(VB_IMPORTANT, loc + "Error, Channel object will not open, "
+                "can not change channels.");
         return false;
     }
 
     QString inputName;
     if (!CheckChannel(channum, inputName))
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "CheckChannel failed. " +
-                QString("Please verify channel '%1'").arg(channum) +
-                " in the \"mythtv-setup\" Channel Editor.");
+        VERBOSE(VB_IMPORTANT, loc + "CheckChannel failed. Please verify " +
+                "the channel in the 'mythtv-setup' Channel Editor.");
         return false;
     }
 
@@ -337,40 +338,25 @@
     if (it == inputs.end())
         return false;
 
-    MSqlQuery query(MSqlQuery::InitCon());
-    QString thequery = QString(
-        "SELECT finetune, freqid, tvformat, freqtable, "
-        "       atscsrcid, commfree, mplexid "
-        "FROM channel, videosource "
-        "WHERE videosource.sourceid = channel.sourceid AND "
-        "      channum = '%1' AND channel.sourceid = '%2'")
-        .arg(channum).arg((*it)->sourceid);
+    // Fetch tuning data from the database.
+    QString tvformat, modulation, freqtable, freqid;
+    int finetune;
+    uint64_t frequency;
+    int mpeg_prog_num;
+    uint atsc_major, atsc_minor, mplexid, tsid, netid;
 
-    query.prepare(thequery);
-
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("fetchtuningparams", query);
-    if (!query.next())
+    if (!ChannelUtil::GetChannelData(
+        (*it)->sourceid, channum,
+        tvformat, modulation, freqtable, freqid,
+        finetune, frequency,
+        mpeg_prog_num, atsc_major, atsc_minor, tsid, netid,
+        mplexid, commfree))
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + QString(
-                    "CheckChannel failed because it could not\n"
-                    "\t\t\tfind channel number '%2' in DB for source '%3'.")
-                .arg(channum).arg((*it)->sourceid));
         return false;
     }
 
-    int     finetune  = query.value(0).toInt();
-    QString freqid    = query.value(1).toString();
-    QString tvformat  = query.value(2).toString();
-    QString freqtable = query.value(3).toString();
-    uint    atscsrcid = query.value(4).toInt();
-    commfree          = query.value(5).toBool();
-    uint    mplexid   = query.value(6).toInt();
-
-    QString modulation;
-    int frequency = ChannelUtil::GetTuningParams(mplexid, modulation);
+    // If the frequency is zeroed out, don't use it directly.
     bool ok = (frequency > 0);
-
     if (!ok)
     {
         frequency = (freqid.toInt(&ok) + finetune) * 1000;
@@ -378,30 +364,34 @@
     }
     bool isFrequency = ok && (frequency > 10000000);
 
-    curchannelname = channum;
-    inputs[currentInputID]->startChanNum = curchannelname;
-
-    VERBOSE(VB_CHANNEL, LOC +
-            QString("freqid = %1, atscsrcid = %2, mplexid = %3")
-            .arg(freqid).arg(atscsrcid).arg(mplexid));
-
-    if (isFrequency)
+    // Tune to proper frequency
+    if ((*it)->externalChanger.isEmpty())
     {
-        if (!Tune(frequency, inputName, modulation))
-            return false;
+        if (isFrequency)
+        {
+            if (!Tune(frequency, inputName, modulation))
+                return false;
+        }
+        else
+        {
+            if (!TuneTo(freqid.toInt()))
+                return false;
+        }
     }
+    else if (!ChangeExternalChannel(freqid))
+        return false;
+
+    // Set the current channum to the new channel's channum
+    curchannelname = QDeepCopy<QString>(channum);
+
+    // Set the major and minor channel for any additional multiplex tuning
+    if (atsc_major || atsc_minor)
+        SetCachedATSCInfo(QString("%1_%2").arg(atsc_major).arg(atsc_minor));
     else
-    {
-        if (!TuneTo(freqid.toInt()))
-            return false;
-    }
+        SetCachedATSCInfo(QString("%1_0").arg(channum));
 
-    QString min_maj = QString("%1_0").arg(channum);
-    if (atscsrcid > 255)
-    {
-        min_maj = QString("%1_%2").arg(atscsrcid >> 8).arg(atscsrcid & 0xff);
-    }
-    SetCachedATSCInfo(min_maj);
+    // Set this as the future start channel for this source
+    inputs[currentInputID]->startChanNum = curchannelname;
 
     return true;
 }
Index: libs/libmythtv/channelbase.cpp
===================================================================
--- libs/libmythtv/channelbase.cpp	(revision 10303)
+++ libs/libmythtv/channelbase.cpp	(working copy)
@@ -32,11 +32,11 @@
 
 ChannelBase::ChannelBase(TVRec *parent)
     : 
-    pParent(parent), channelorder("channum + 0"), curchannelname(""),
+    pParent(parent), curchannelname(""),
     currentInputID(-1), commfree(false), cardid(0),
-    currentATSCMajorChannel(-1), currentATSCMinorChannel(-1),
-    currentProgramNum(-1), currentOriginalNetworkID(-1), 
-    currentTransportID(-1)
+    currentProgramNum(-1),
+    currentATSCMajorChannel(0), currentATSCMinorChannel(0),
+    currentTransportID(0),      currentOriginalNetworkID(0)
 {
 }
 
@@ -46,28 +46,39 @@
 
 bool ChannelBase::SetChannelByDirection(ChannelChangeDirection dir)
 {
-    bool fTune = false;
-    uint chanid;
-    QString start, nextchan;
-    start = nextchan = ChannelUtil::GetNextChannel(
-        GetCardID(), GetCurrentInput(), GetCurrentName(),
-        dir,         channelorder,      chanid);
+    uint startchanid = GetNextChannel(GetCurrentName(), dir);
+    uint nextchanid  = startchanid;
 
+    bool ok = false;
     do
     {
-       fTune = SetChannelByString(nextchan);
-       if (!fTune)
-       {
-           nextchan = ChannelUtil::GetNextChannel(
-               GetCardID(), GetCurrentInput(), GetCurrentName(),
-               dir,         channelorder,      chanid);
-       }
+        if (!(ok = SetChannelByString(ChannelUtil::GetChanNum(nextchanid))))
+            nextchanid = GetNextChannel(nextchanid, dir);
     }
-    while (!fTune && nextchan != start);
+    while (!ok && (nextchanid != startchanid));
 
-    return fTune;
+    return ok;
 }
 
+uint ChannelBase::GetNextChannel(uint chanid, int direction) const
+{
+    InputMap::const_iterator it = inputs.find(currentInputID);
+    if (it == inputs.end())
+        return 0;
+
+    return ChannelUtil::GetNextChannel((*it)->channels, chanid, direction);
+}
+
+uint ChannelBase::GetNextChannel(const QString &channum, int direction) const
+{
+    InputMap::const_iterator it = inputs.find(currentInputID);
+    if (it == inputs.end())
+        return 0;
+
+    uint chanid = ChannelUtil::GetChanID((*it)->sourceid, channum);
+    return GetNextChannel(chanid, direction);
+}
+
 int ChannelBase::GetNextInputNum(void) const
 {
     // Exit early if inputs don't exist..
@@ -349,10 +360,10 @@
     int chansep = chan.find("_");
 
     currentProgramNum        = -1;
-    currentOriginalNetworkID = -1;
-    currentTransportID       = -1;
-    currentATSCMajorChannel  = -1;
-    currentATSCMinorChannel  = -1;
+    currentOriginalNetworkID = 0;
+    currentTransportID       = 0;
+    currentATSCMajorChannel  = 0;
+    currentATSCMinorChannel  = 0;
 
     if (progsep >= 0)
     {
@@ -375,12 +386,12 @@
         }
     }
 
-    if (currentATSCMinorChannel >= 0)
+    if (currentATSCMinorChannel > 0)
         VERBOSE(VB_CHANNEL,
                 QString("ChannelBase(%1)::SetCachedATSCInfo(%2): %3_%4")
                 .arg(GetDevice()).arg(chan)
                 .arg(currentATSCMajorChannel).arg(currentATSCMinorChannel));
-    else if ((-1 == currentATSCMajorChannel) && (-1 == currentProgramNum))
+    else if ((0 == currentATSCMajorChannel) && (0 == currentProgramNum))
         VERBOSE(VB_CHANNEL,
                 QString("ChannelBase(%1)::SetCachedATSCInfo(%2): RESET")
                 .arg(GetDevice()).arg(chan));
@@ -486,10 +497,16 @@
         uint inputcardid = query.value(6).toUInt();
         inputcardid = (inputcardid) ? inputcardid : cardid;
 
+        uint sourceid = query.value(5).toUInt();
+        DBChanList channels = ChannelUtil::GetChannels(sourceid, false);
+
+        QString order = gContext->GetSetting("ChannelOrdering", "channum");
+        ChannelUtil::SortChannels(channels, order);
+
         inputs[query.value(0).toUInt()] = new InputBase(
             query.value(1).toString(), query.value(2).toString(),
             query.value(3).toString(), query.value(4).toString(),
-            query.value(5).toUInt(),   inputcardid);
+            sourceid, inputcardid, channels);
     }
 
     // Set initial input to first connected input
Index: libs/libmythtv/dvbchannel.h
===================================================================
--- libs/libmythtv/dvbchannel.h	(revision 10303)
+++ libs/libmythtv/dvbchannel.h	(working copy)
@@ -76,7 +76,7 @@
   private:
     int  GetChanID(void) const;
     bool GetTransportOptions(int mplexid);
-    bool GetChannelOptions(const QString &channum);
+    bool InitChannelParams(uint sourceid, const QString &channum);
 
     void CheckOptions();
     bool CheckModulation(fe_modulation_t modulation) const;
Index: libs/libmythtv/eithelper.h
===================================================================
--- libs/libmythtv/eithelper.h	(revision 10303)
+++ libs/libmythtv/eithelper.h	(working copy)
@@ -60,13 +60,15 @@
     uint GetGPSOffset(void) const { return (uint) (0 - gps_offset); }
 
     void SetGPSOffset(uint _gps_offset) { gps_offset = 0 - _gps_offset; }
-    void SetFixup(uint atscsrcid, uint eitfixup);
+    void SetFixup(uint atsc_major, uint atsc_minor, uint eitfixup);
     void SetLanguagePreferences(const QStringList &langPref);
     void SetSourceID(uint _sourceid);
 
 #ifdef USING_BACKEND
-    void AddEIT(uint atscsrcid, const EventInformationTable *eit);
-    void AddETT(uint atscsrcid, const ExtendedTextTable     *ett);
+    void AddEIT(uint atsc_major, uint atsc_minor,
+                const EventInformationTable *eit);
+    void AddETT(uint atsc_major, uint atsc_minor,
+                const ExtendedTextTable     *ett);
     void AddEIT(const DVBEventInformationTable *eit);
 #else // if !USING_BACKEND
     void AddEIT(uint, const EventInformationTable*) {}
@@ -77,10 +79,10 @@
     void PruneCache(uint timestamp);
 
   private:
-    uint GetChanID(uint atscsrcid);
+    uint GetChanID(uint atsc_major, uint atsc_minor);
     uint GetChanID(uint serviceid, uint networkid, uint transportid);
 
-    void CompleteEvent(uint atscsrcid,
+    void CompleteEvent(uint atsc_major, uint atsc_minor,
                        const ATSCEvent &event,
                        const QString   &ett);
 
Index: libs/libmythtv/datadirect.cpp
===================================================================
--- libs/libmythtv/datadirect.cpp	(revision 10303)
+++ libs/libmythtv/datadirect.cpp	(working copy)
@@ -30,11 +30,9 @@
 static QString html_escape(QString str);
 static void    get_atsc_stuff(QString channum, int sourceid, int freqid,
                               int &major, int &minor, long long &freq);
-static uint    create_atscsrcid(QString chan_major, QString chan_minor);
 static QString process_dd_station(uint sourceid,
                                   QString  chan_major, QString  chan_minor,
-                                  QString &tvformat,   uint    &freqid,
-                                  uint    &atscsrcid);
+                                  QString &tvformat,   uint    &freqid);
 static void    update_channel_basic(uint    sourceid,   bool    insert,
                                     QString xmltvid,    QString callsign,
                                     QString name,       uint    freqid,
@@ -680,18 +678,18 @@
         "UPDATE channel "
         "SET callsign  = :CALLSIGN,  name   = :NAME, "
         "    channum   = :CHANNUM,   freqid = :FREQID, "
-        "    atscsrcid = :ATSCSRCID "
+        "    atsc_major_chan = :MAJORCHAN, "
+        "    atsc_minor_chan = :MINORCHAN "
         "WHERE xmltvid = :STATIONID AND sourceid = :SOURCEID");
 
     while (dd_station_info.next())        
     {
-        uint    atscsrcid  = 0;
         uint    freqid     = dd_station_info.value(3).toUInt();
         QString chan_major = dd_station_info.value(4).toString();
         QString chan_minor = dd_station_info.value(5).toString();
         QString tvformat   = QString::null;
         QString channum    = process_dd_station(
-            sourceid, chan_major, chan_minor, tvformat, freqid, atscsrcid);
+            sourceid, chan_major, chan_minor, tvformat, freqid);
 
         chan_update_q.bindValue(":CALLSIGN",  dd_station_info.value(0));
         chan_update_q.bindValue(":NAME",      dd_station_info.value(1));
@@ -699,7 +697,8 @@
         chan_update_q.bindValue(":CHANNUM",   channum);
         chan_update_q.bindValue(":SOURCEID",  sourceid);
         chan_update_q.bindValue(":FREQID",    freqid);
-        chan_update_q.bindValue(":ATSCSRCID", atscsrcid);
+        chan_update_q.bindValue(":MAJORCHAN", chan_major.toUInt());
+        chan_update_q.bindValue(":MINORCHAN", chan_minor.toUInt());
 
         if (!chan_update_q.exec())
         {
@@ -1756,35 +1755,22 @@
     }
 }
 
-static uint create_atscsrcid(QString chan_major, QString chan_minor)
-{
-    bool ok;
-    uint major = chan_major.toUInt(&ok), atscsrcid = 0;
-    if (!ok)
-        return atscsrcid;
-
-    atscsrcid = major << 8;
-    if (chan_minor.isEmpty())
-        return atscsrcid;
-
-    return atscsrcid | chan_minor.toUInt();
-}
-
 static QString process_dd_station(
     uint sourceid, QString chan_major, QString chan_minor,
-    QString &tvformat, uint &freqid, uint &atscsrcid)
+    QString &tvformat, uint &freqid)
 {
     QString channum = chan_major;
-    atscsrcid = create_atscsrcid(chan_major, chan_minor);
+    bool ok;
+    uint minor = chan_minor.toUInt(&ok);
+
     tvformat = "Default";
 
-    if (atscsrcid & 0xff)
+    if (minor && ok)
     {
         tvformat = "atsc";
         channum += SourceUtil::GetChannelSeparator(sourceid) + chan_minor;
     }
-
-    if (!freqid && !(atscsrcid & 0xff))
+    else if (!freqid)
         freqid = chan_major.toInt();
 
     return channum;
@@ -1797,19 +1783,21 @@
 {
     callsign = (callsign.isEmpty()) ? name : callsign;
 
-    uint atscsrcid;
     QString tvformat;
     QString channum = process_dd_station(
-        sourceid, chan_major, chan_minor, tvformat, freqid, atscsrcid);
+        sourceid, chan_major, chan_minor, tvformat, freqid);
 
     // First check if channel already in DB, but without xmltvid
     MSqlQuery query(MSqlQuery::DDCon());
     query.prepare("SELECT chanid FROM channel "
                   "WHERE sourceid = :SOURCEID AND "
-                  "      (channum=:CHANNUM OR atscsrcid=:ATSCSRCID)");
+                  "      ( channum = :CHANNUM OR "
+                  "        ( atsc_major_chan = :MAJORCHAN AND "
+                  "          atsc_minor_chan = :MINORCHAN ) )");
     query.bindValue(":SOURCEID",  sourceid);
     query.bindValue(":CHANNUM",   channum);
-    query.bindValue(":ATSCSRCID", atscsrcid);
+    query.bindValue(":MAJORCHAN", chan_major.toUInt());
+    query.bindValue(":MINORCHAN", chan_minor.toUInt());
 
     if (!query.exec() || !query.isActive())
     {
Index: libs/libmythtv/channelutil.cpp
===================================================================
--- libs/libmythtv/channelutil.cpp	(revision 10303)
+++ libs/libmythtv/channelutil.cpp	(working copy)
@@ -193,10 +193,14 @@
 
         // Use the frequency we already have for this mplex
         // as it may be one of the other_frequencies for this mplex
-        QString modulation;
         int mux = ChannelUtil::GetMplexID(sourceid, tsid, netid);
-        if (mux != -1)
-            freq = ChannelUtil::GetTuningParams(mux, modulation);
+        if (mux > 0)
+        {
+            QString dummy_mod;
+            uint dummy_tsid, dummy_netid;
+            ChannelUtil::GetTuningParams(mux, dummy_mod, freq,
+                                         dummy_tsid, dummy_netid);
+        }
 
         mux = ChannelUtil::CreateMultiplex(
             sourceid,            "dvb",
@@ -566,29 +570,37 @@
     return -1;
 }
 
-int ChannelUtil::GetTuningParams(int mplexid, QString &modulation)
+bool ChannelUtil::GetTuningParams(uint      mplexid,
+                                  QString  &modulation,
+                                  uint64_t &frequency,
+                                  uint     &dvb_transportid,
+                                  uint     &dvb_networkid)
 {
-    if (mplexid <= 0)
-        return -1;
+    if (!mplexid)
+        return false;
 
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare(QString("SELECT frequency, modulation "
-                          "FROM dtv_multiplex "
-                          "WHERE mplexid=%1").arg(mplexid));
+    query.prepare(
+        "SELECT transportid, networkid, frequency, modulation "
+        "FROM dtv_multiplex "
+        "WHERE mplexid = :MPLEXID");
+    query.bindValue(":MPLEXID", mplexid);
 
     if (!query.exec() || !query.isActive())
     {
         MythContext::DBError("GetTuningParams failed ", query);
-        return -1;
+        return false;
     }
 
-    if (!query.size())
-        return -1;
+    if (!query.next())
+        return false;
 
-    query.next();
+    dvb_transportid = query.value(0).toUInt();
+    dvb_networkid   = query.value(1).toUInt();
+    frequency       = (uint64_t) query.value(2).toDouble(); // Qt 3.1 compat
+    modulation      = query.value(3).toString();
 
-    modulation = query.value(1).toString();
-    return query.value(0).toInt(); 
+    return true;
 }
 
 QString ChannelUtil::GetChannelStringField(int chan_id, const QString &field)
@@ -796,269 +808,74 @@
     return query.exec();
 }
 
-QString ChannelUtil::GetNextChannel(
-    uint           cardid,       const QString &inputname,
-    const QString &channum,      int            direction,
-    QString       &channelorder, uint          &chanid)
-{
-    chanid = 0;
-    bool isNum = true;
-    channum.toULong(&isNum);
-
-    if (!isNum && channelorder == "channum + 0")
-    {
-        bool has_atsc = GetChannelValueInt("atscsrcid", cardid,
-                                           inputname, channum);
-        channelorder = (has_atsc) ? "atscsrcid" : "channum";
-        if (!has_atsc)
-        {
-            QString msg = QString(
-                "Your channel ordering method \"channel number (numeric)\"\n"
-                "\t\t\twill not work with channels like: '%1' \n"
-                "\t\t\tConsider switching to order by \"database order\"  \n"
-                "\t\t\tor \"channel number (alpha)\" in the general       \n"
-                "\t\t\tsettings section of the frontend setup             \n"
-                "\t\t\tSwitched to '%2' order.")
-                .arg(channum).arg(channelorder);
-            VERBOSE(VB_IMPORTANT, LOC + msg);
-        }
-    }
-
-    MSqlQuery query(MSqlQuery::InitCon());
-
-    QString querystr = QString(
-        "SELECT %1 "
-        "FROM channel,capturecard,cardinput "
-        "WHERE channel.channum      = :CHANNUM           AND "
-        "      channel.sourceid     = cardinput.sourceid AND "
-        "      cardinput.cardid     = capturecard.cardid AND "
-        "      capturecard.cardid   = :CARDID            AND "
-        "      capturecard.hostname = :HOSTNAME").arg(channelorder);
-    query.prepare(querystr);
-    query.bindValue(":CHANNUM",  channum);
-    query.bindValue(":CARDID",   cardid);
-    query.bindValue(":HOSTNAME", gContext->GetHostName());
-
-    QString id = QString::null;
-
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("getnextchannel 1", query);
-    else if (query.next())
-        id = query.value(0).toString();
-
-    if (id.isEmpty())
-    {
-        QString msg = QString(
-            "Channel: '%1' was not found in the database.\n"
-            "\t\t\tMost likely, the default channel set for this input\n"
-            "\t\t\tcardid %2, input '%3'\n"
-            "\t\t\tin setup is wrong\n")
-            .arg(channum).arg(cardid).arg(inputname);
-        VERBOSE(VB_IMPORTANT, LOC + msg);
-
-        querystr = QString(
-            "SELECT %1 "
-            "FROM channel, capturecard, cardinput "
-            "WHERE channel.sourceid     = cardinput.sourceid AND "
-            "      cardinput.cardid     = capturecard.cardid AND "
-            "      capturecard.cardid   = :CARDID            AND "
-            "      capturecard.hostname = :HOSTNAME "
-            "ORDER BY %2 "
-            "LIMIT 1").arg(channelorder).arg(channelorder);
-        query.prepare(querystr);
-        query.bindValue(":CARDID",   cardid);
-        query.bindValue(":HOSTNAME", gContext->GetHostName());
-
-        if (!query.exec() || !query.isActive())
-            MythContext::DBError("getnextchannel 2", query);
-        else if (query.next())
-            id = query.value(0).toString();
-    }
-
-    if (id.isEmpty())
-    {
-        VERBOSE(VB_IMPORTANT, LOC_ERR +
-                "Couldn't find any channels in the database,\n"
-                "\t\t\tplease make sure your inputs are associated\n"
-                "\t\t\tproperly with your cards.");
-        return "";
-    }
-
-    // Now let's try finding the next channel in the desired direction
-    QString comp = ">";
-    QString ordering = "";
-    QString fromfavorites = "";
-    QString wherefavorites = "";
-
-    if (direction == CHANNEL_DIRECTION_DOWN)
-    {
-        comp = "<";
-        ordering = " DESC ";
-    }
-    else if (direction == CHANNEL_DIRECTION_FAVORITE)
-    {
-        fromfavorites = ",favorites";
-        wherefavorites = "AND favorites.chanid = channel.chanid";
-    }
-    else if (direction == CHANNEL_DIRECTION_SAME)
-    {
-        comp = "=";
-    }
-
-    QString wherepart = QString(
-        "cardinput.cardid     = capturecard.cardid AND "
-        "capturecard.cardid   = :CARDID            AND "
-        "capturecard.hostname = :HOSTNAME          AND "
-        "channel.visible      = 1                  AND "
-        "cardinput.sourceid = channel.sourceid ");
-
-    querystr = QString(
-        "SELECT channel.channum, channel.chanid "
-        "FROM channel, capturecard, cardinput%1 "
-        "WHERE channel.%2 %3 :ID %4 AND "
-        "      %5 "
-        "ORDER BY channel.%6 %7 "
-        "LIMIT 1")
-        .arg(fromfavorites).arg(channelorder)
-        .arg(comp).arg(wherefavorites)
-        .arg(wherepart).arg(channelorder).arg(ordering);
-
-    query.prepare(querystr);
-    query.bindValue(":CARDID",   cardid);
-    query.bindValue(":HOSTNAME", gContext->GetHostName());
-    query.bindValue(":ID",       id);
-
-    if (!query.exec() || !query.isActive())
-    {
-        MythContext::DBError("getnextchannel 3", query);
-    }
-    else if (query.next())
-    {
-        chanid = query.value(1).toUInt();
-        return query.value(0).toString();
-    }
-    else
-    {
-        // Couldn't find the channel going in the desired direction, 
-        // so loop around and find it on the flip side...
-        comp = "<";
-        if (direction == CHANNEL_DIRECTION_DOWN) 
-            comp = ">";
-
-        // again, %9 is the limit for this
-        querystr = QString(
-            "SELECT channel.channum, channel.chanid "
-            "FROM channel, capturecard, cardinput%1 "
-            "WHERE channel.%2 %3 :ID %4 AND "
-            "      %5 "
-            "ORDER BY channel.%6 %7 "
-            "LIMIT 1")
-            .arg(fromfavorites).arg(channelorder)
-            .arg(comp).arg(wherefavorites)
-            .arg(wherepart).arg(channelorder).arg(ordering);
-
-        query.prepare(querystr);
-        query.bindValue(":CARDID",   cardid);
-        query.bindValue(":HOSTNAME", gContext->GetHostName());
-        query.bindValue(":ID",       id); 
-
-        if (!query.exec() || !query.isActive())
-        {
-            MythContext::DBError("getnextchannel", query);
-        }
-        else if (query.next())
-        {
-            chanid = query.value(1).toUInt();
-            return query.value(0).toString();
-        }
-        else
-        {
-            VERBOSE(VB_IMPORTANT, "getnextchannel, query failed: "<<querystr);
-        }
-    }
-
-    // just stay on same channel
-    chanid = max(GetChannelValueInt("chanid", cardid, inputname, channum), 0);
-    return channum;
-}
-
 int ChannelUtil::GetChanID(int mplexid,       int service_transport_id,
                            int major_channel, int minor_channel,
                            int program_number)
 {
-    // Currently we don't use the service transport id,
-    // but we should use it according to ATSC std 65.
-    (void) service_transport_id;
-    
-    MSqlQuery query(MSqlQuery::InitCon());
+    MSqlQuery query(MSqlQuery::DDCon());
 
-    // This works for transports inserted by a scan
-    query.prepare(QString("SELECT chanid FROM channel "
-                          "WHERE serviceID=%1 AND mplexid=%2")
-                  .arg(program_number).arg(mplexid));
-    
-    if (!query.exec() || !query.isActive())
-    {
-        MythContext::DBError("Selecting channel/dtv_multiplex 1", query);
-        return -1;
-    }
-    if (query.size())
-    {
-        query.next();
-        return query.value(0).toInt();
-    }
-
-    if (major_channel <= 0)
-        return -1;
-
     // find source id, so we can find manually inserted ATSC channels
-    query.prepare(QString("SELECT sourceid FROM dtv_multiplex "
-                          "WHERE mplexid=%2").arg(mplexid));
+    query.prepare("SELECT sourceid "
+                  "FROM dtv_multiplex "
+                  "WHERE mplexid = :MPLEXID");
+    query.bindValue(":MPLEXID", mplexid);
     if (!query.exec() || !query.isActive() || !query.size())
     {
         MythContext::DBError("Selecting channel/dtv_multiplex 2", query);
         return -1;
     }
-    query.next();
+    if (!query.next())
+        return -1;
+
     int source_id = query.value(0).toInt();
 
-    uint atsc_src_id = (major_channel << 8) | (minor_channel & 0xff);
-
-    // Find manually inserted/edited channels...
     QString qstr[] = 
     {
-        // find based on pcHDTV formatted major and minor channels
+        // find a proper ATSC channel
+        QString("SELECT chanid FROM channel,dtv_multiplex "
+                "WHERE channel.sourceid          = %1 AND "
+                "      atsc_major_chan           = %2 AND "
+                "      atsc_minor_chan           = %3 AND "
+                "      dtv_multiplex.transportid = %4 AND "
+                "      dtv_multiplex.mplexid     = %5 AND "
+                "      dtv_multiplex.sourceid    = channel.sourceid AND "
+                "      dtv_multiplex.mplexid     = channel.mplexid")
+        .arg(source_id).arg(major_channel).arg(minor_channel)
+        .arg(service_transport_id).arg(mplexid),
+
+        // Find manually inserted/edited channels in order of scariness.
+
+        // find renamed channel, where atsc is valid
         QString("SELECT chanid FROM channel "
+                "WHERE sourceid=%1 AND "
+                "atsc_major_chan=%2 AND "
+                "atsc_minor_chan=%3")
+        .arg(source_id).arg(major_channel).arg(minor_channel),
+        // find based on mpeg program number and mplexid alone
+        QString("SELECT chanid FROM channel "
+                "WHERE sourceid=%1 AND serviceID=%1 AND mplexid=%2")
+        .arg(source_id).arg(program_number).arg(mplexid),
+        // find based on OLD pcHDTV formatted major and minor channels
+        QString("SELECT chanid FROM channel "
                 "WHERE sourceid=%1 AND channum='%2_%3'")
         .arg(source_id).arg(major_channel).arg(minor_channel),
-        // find based on pcHDTV formatted major channel and program number
-        // really old format, still used in freq_id, but we don't check that.
+        // find based on OLD pcHDTV formatted major channel and program number
         QString("SELECT chanid FROM channel "
                 "WHERE sourceid=%1 AND channum='%2-%3'")
         .arg(source_id).arg(major_channel).arg(program_number),
-        // find based on DVB formatted major and minor channels
+        // find based on OLD DVB formatted major and minor channels
         QString("SELECT chanid FROM channel "
                 "WHERE sourceid=%1 AND channum='%2%3'")
         .arg(source_id).arg(major_channel).arg(minor_channel),
-        // find renamed channel, where atscsrcid is valid
-        QString("SELECT chanid FROM channel "
-                "WHERE sourceid=%1 AND atscsrcid=%2")
-        .arg(source_id).arg(atsc_src_id),
     };
 
-    for (uint i = 0; i < 4; i++)
+    for (uint i = 0; i < 6; i++)
     {
         query.prepare(qstr[i]);
         if (!query.exec() || !query.isActive())
-        {
             MythContext::DBError("Selecting channel/dtv_multiplex 3", query);
-            return -1;
-        }
-        if (query.size())
-        {
-            query.next();
+        if (query.next())
             return query.value(0).toInt();
-        }
     }
 
     return -1;
@@ -1164,17 +981,17 @@
     QString chanNum = (chan_num == "-1") ?
         QString::number(service_id) : chan_num;
 
-    uint atsc_src_id = (atsc_major_channel << 8) | (atsc_minor_channel & 0xff);
-
     query.prepare(
         "INSERT INTO channel "
         "  (chanid,        channum,    sourceid,   callsign,  "
-        "   name,          mplexid,    serviceid,  atscsrcid, "
+        "   name,          mplexid,    serviceid,             "
+        "   atsc_major_chan,           atsc_minor_chan,       "
         "   useonairguide, visible,    freqid,     tvformat,  "
         "   icon,          xmltvid) "
         "VALUES "
         "  (:CHANID,       :CHANNUM,   :SOURCEID,  :CALLSIGN,  "
-        "   :NAME,         :MPLEXID,   :SERVICEID, :ATSCSRCID, "
+        "   :NAME,         :MPLEXID,   :SERVICEID,             "
+        "   :MAJORCHAN,                :MINORCHAN,             "
         "   :USEOAG,       :VISIBLE,   :FREQID,    :TVFORMAT,  "
         "   :ICON,         :XMLTVID)");
 
@@ -1188,7 +1005,8 @@
         query.bindValue(":MPLEXID",   db_mplexid);
 
     query.bindValue(":SERVICEID", service_id);
-    query.bindValue(":ATSCSRCID", atsc_src_id);
+    query.bindValue(":MAJORCHAN", atsc_major_channel);
+    query.bindValue(":MINORCHAN", atsc_minor_channel);
     query.bindValue(":USEOAG",    use_on_air_guide);
     query.bindValue(":VISIBLE",   !hidden);
     (void) hidden_in_guide; // MythTV can't hide the channel in just the guide.
@@ -1223,19 +1041,19 @@
 {
     MSqlQuery query(MSqlQuery::InitCon());
 
-    uint atsc_src_id = (atsc_major_channel << 8) | (atsc_minor_channel & 0xff);
+    query.prepare(
+        "UPDATE channel "
+        "SET mplexid         = :MPLEXID,   serviceid       = :SERVICEID, "
+        "    atsc_major_chan = :MAJORCHAN, atsc_minor_chan = :MINORCHAN, "
+        "    callsign        = :CALLSIGN,  name            = :NAME,      "
+        "    channum         = :CHANNUM,   freqid          = :FREQID,    "
+        "    tvformat        = :TVFORMAT,  sourceid        = :SOURCEID   "
+        "WHERE chanid=:CHANID");
 
-    query.prepare("UPDATE channel "
-                  "SET mplexid=:MPLEXID,     serviceid=:SERVICEID, "
-                  "    atscsrcid=:ATSCSRCID, callsign=:CALLSIGN, "
-                  "    name=:NAME,           channum=:CHANNUM, "
-                  "    freqid=:FREQID,       tvformat=:TVFORMAT, "
-                  "    sourceid=:SOURCEID "
-                  "WHERE chanid=:CHANID");
-
     query.bindValue(":MPLEXID",   db_mplexid);
     query.bindValue(":SERVICEID", service_id);
-    query.bindValue(":ATSCSRCID", atsc_src_id);
+    query.bindValue(":MAJORCHAN", atsc_major_channel);
+    query.bindValue(":MINORCHAN", atsc_minor_channel);
     query.bindValue(":CALLSIGN",  callsign.utf8());
     query.bindValue(":NAME",      service_name.utf8());
     query.bindValue(":SOURCEID",  source_id);
@@ -1244,7 +1062,7 @@
         query.bindValue(":CHANNUM",   chan_num);
     if (freqid > 0)
         query.bindValue(":FREQID",    freqid);
-    if (atsc_major_channel > 0)
+    if (atsc_minor_channel > 0)
         query.bindValue(":TVFORMAT",  "ATSC");
 
     if (!query.exec() || !query.isActive())
@@ -1321,3 +1139,244 @@
 
     return query.value(0).toString();
 }
+
+                    
+bool ChannelUtil::GetATSCChannel(uint sourceid, const QString &channum,
+                                 uint &major,   uint          &minor)
+{
+    major = minor = 0;
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare(
+        "SELECT atsc_major_chan, atsc_minor_chan "
+        "FROM channel "
+        "WHERE channum  = :CHANNUM AND "
+        "      sourceid = :SOURCEID");
+
+    query.bindValue(":SOURCEID", sourceid);
+    query.bindValue(":CHANNUM",  channum);
+
+    if (!query.exec() || !query.isActive())
+        MythContext::DBError("getchannelvalue", query);
+    else if (query.next())
+    {
+        major = query.value(0).toUInt();
+        minor = query.value(1).toUInt();
+        return true;
+    }
+
+    return false;
+}
+
+bool ChannelUtil::GetChannelData(
+    uint    sourceid,         const QString &channum,
+    QString &tvformat,        QString       &modulation,
+    QString &freqtable,       QString       &freqid,
+    int     &finetune,        uint64_t      &frequency,
+    int     &mpeg_prog_num,
+    uint    &atsc_major,      uint          &atsc_minor,
+    uint    &dvb_transportid, uint          &dvb_networkid,
+    uint    &mplexid,
+    bool    &commfree)
+{
+    tvformat      = modulation = freqtable = freqid = QString::null;
+    finetune      = 0;
+    frequency     = 0;
+    mpeg_prog_num = -1;
+    atsc_major    = atsc_minor = mplexid = 0;
+    commfree      = false;
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare(
+        "SELECT finetune, freqid, tvformat, freqtable, "
+        "       commfree, mplexid, "
+        "       atsc_major_chan, atsc_minor_chan, serviceid "
+        "FROM channel, videosource "
+        "WHERE videosource.sourceid = channel.sourceid AND "
+        "      channum              = :CHANNUM         AND "
+        "      channel.sourceid     = :SOURCEID");
+    query.bindValue(":CHANNUM",  channum);
+    query.bindValue(":SOURCEID", sourceid);
+
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("GetChannelData", query);
+        return false;
+    }
+    else if (!query.next())
+    {
+        VERBOSE(VB_IMPORTANT, QString(
+                    "GetChannelData() failed because it could not\n"
+                    "\t\t\tfind channel number '%1' in DB for source '%2'.")
+                .arg(channum).arg(sourceid));
+        return false;
+    }
+
+    finetune      = query.value(0).toInt();
+    freqid        = query.value(1).toString();
+    tvformat      = query.value(2).toString();
+    freqtable     = query.value(3).toString();
+    commfree      = query.value(4).toBool();
+    mplexid       = query.value(5).toUInt();
+    atsc_major    = query.value(6).toUInt();
+    atsc_minor    = query.value(7).toUInt();
+    mpeg_prog_num = query.value(8).toUInt();
+
+    if (!mplexid)
+        return true;
+
+    return GetTuningParams(mplexid, modulation, frequency,
+                           dvb_transportid, dvb_networkid);
+}
+
+DBChanList ChannelUtil::GetChannels(uint sourceid, bool vis_only, QString grp)
+{
+    DBChanList list;
+    QMap<uint,uint> favorites;
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare(
+        "SELECT chanid, favid "
+        "FROM favorites");
+    if (!query.exec() || !query.isActive())
+        MythContext::DBError("get channels -- favorites", query);
+    else
+    {
+        while (query.next())
+            favorites[query.value(0).toUInt()] = query.value(1).toUInt();
+    }
+
+    QString qstr =
+        "SELECT channum, callsign, chanid, "
+        "       atsc_major_chan, atsc_minor_chan, "
+        "       name, icon "
+        "FROM channel ";
+
+    if (sourceid)
+        qstr += QString("WHERE sourceid='%1' ").arg(sourceid);
+    else
+        qstr += ",cardinput,capturecard "
+            "WHERE cardinput.sourceid = channel.sourceid   AND "
+            "      cardinput.cardid   = capturecard.cardid     ";
+
+    if (vis_only)
+        qstr += "AND visible=1 ";
+
+    if (!grp.isEmpty())
+        qstr += QString("GROUP BY %1 ").arg(grp);
+
+    query.prepare(qstr);
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("get channels -- sourceid", query);
+        return list;
+    }
+
+    while (query.next())
+    {
+        if (query.value(0).toString().isEmpty() || !query.value(2).toUInt())
+            continue; // skip if channum blank, or chanid empty
+
+        DBChannel chan(
+            query.value(0).toString(),                    /* channum    */
+            QString::fromUtf8(query.value(1).toString()), /* callsign   */
+            query.value(2).toUInt(),                      /* chanid     */
+            query.value(3).toUInt(),                      /* ATSC major */
+            query.value(4).toUInt(),                      /* ATSC minor */
+            favorites[query.value(2).toUInt()],           /* favid      */
+            QString::fromUtf8(query.value(5).toString()), /* name       */
+            query.value(6).toString());                   /* icon       */
+
+        list.push_back(chan);
+    }
+
+    return list;
+}
+
+inline bool lt_callsign(const DBChannel &a, const DBChannel &b)
+{
+    return QString::localeAwareCompare(a.callsign, b.callsign) < 0;
+}
+
+inline bool lt_smart(const DBChannel &a, const DBChannel &b)
+{
+    int cmp = 0;
+    if (a.major_chan && b.major_chan)
+    {
+        if ((cmp = a.major_chan - b.major_chan))
+            return cmp < 0;
+
+        if ((cmp = a.minor_chan - b.minor_chan))
+            return cmp < 0;
+    }
+
+    bool isIntA, isIntB;
+    int a_int = a.channum.toUInt(&isIntA);
+    int b_int = a.channum.toUInt(&isIntB);
+    if (isIntA && isIntB)
+    {
+        cmp = a_int - b_int;
+        if (cmp)
+            return cmp < 0;
+    }
+    else
+    {
+        return QString::localeAwareCompare(a.channum, b.channum) < 0;
+    }
+
+    return lt_callsign(a,b);
+}
+
+void ChannelUtil::SortChannels(DBChanList &list, const QString &order)
+{
+    if (order.lower() == "callsign")
+        sort(list.begin(), list.end(), lt_callsign);
+    else /* if (sortorder == "channum") */
+        sort(list.begin(), list.end(), lt_smart);
+}
+
+uint ChannelUtil::GetNextChannel(const DBChanList &sorted,
+                                 uint old_chanid, int direction)
+{
+    DBChanList::const_iterator it =
+        find(sorted.begin(), sorted.end(), old_chanid);
+
+    if (it == sorted.end())
+        it = sorted.begin(); // not in list, pretend we are on first channel
+
+    if (it == sorted.end())
+        return 0; // no channels..
+
+    if (CHANNEL_DIRECTION_DOWN == direction)
+    {
+        if (it == sorted.begin())
+            return sorted.rbegin()->chanid;
+        it--;
+    }
+    else if (CHANNEL_DIRECTION_UP == direction)
+    {
+        it++;
+        if (it == sorted.end())
+            it = sorted.begin();
+    }
+    else if (CHANNEL_DIRECTION_FAVORITE == direction)
+    {
+        DBChanList::const_iterator it_orig = it;
+        for (;;++it)
+        {
+            if (it == sorted.end())
+                it = sorted.begin();
+
+            if (it == it_orig)
+            {
+                if (!it->favorite)
+                    ++it;
+                break; // no (other?) favorites
+            }
+
+            if (it->favorite)
+                break; // found next favorite
+        }
+    }
+
+    return it->chanid;
+}
Index: libs/libmythtv/mpeg/atscstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/atscstreamdata.cpp	(revision 10303)
+++ libs/libmythtv/mpeg/atscstreamdata.cpp	(working copy)
@@ -117,7 +117,7 @@
     _eit_version.clear();
     _eit_section_seen.clear();
 
-    _sourceid_to_atscsrcid.clear();
+    _sourceid_to_atsc_maj_min.clear();
     _atsc_eit_pids.clear();
     _atsc_ett_pids.clear();
 
@@ -275,9 +275,9 @@
             for (uint i = 0; i < _atsc_eit_listeners.size(); i++)
                 _atsc_eit_listeners[i]->HandleEIT(pid, &eit);
 
-            const uint atscsrcid = GetATSCSRCID(eit.SourceID());
-            if (atscsrcid && _eit_helper)
-                _eit_helper->AddEIT(atscsrcid, &eit);
+            const uint mm = GetATSCMajorMinor(eit.SourceID());
+            if (mm && _eit_helper)
+                _eit_helper->AddEIT(mm >> 16, mm & 0xffff, &eit);
                 
             return true;
         }
@@ -291,9 +291,9 @@
 
             if (ett.IsEventETM() && _eit_helper) // Guide ETTs
             {
-                const uint atscsrcid = GetATSCSRCID(ett.SourceID());
-                if (atscsrcid)
-                    _eit_helper->AddETT(atscsrcid, &ett);
+                const uint mm = GetATSCMajorMinor(ett.SourceID());
+                if (mm)
+                    _eit_helper->AddETT(mm >> 16, mm & 0xffff, &ett);
             }
 
             return true;
@@ -452,7 +452,7 @@
     for (uint i = 0; i < _atsc_main_listeners.size(); i++)
         _atsc_main_listeners[i]->HandleVCT(tsid, vct);
 
-    _sourceid_to_atscsrcid.clear();
+    _sourceid_to_atsc_maj_min.clear();
     for (uint i = 0; i < vct->ChannelCount() ; i++)
     {
         if (vct->IsHiddenInGuide(i))
@@ -477,8 +477,8 @@
                 .arg(vct->MajorChannel(i))
                 .arg(vct->MinorChannel(i)));
 
-        _sourceid_to_atscsrcid[vct->SourceID(i)] =
-            vct->MajorChannel(i) << 8 | vct->MinorChannel(i);
+        _sourceid_to_atsc_maj_min[vct->SourceID(i)] =
+            vct->MajorChannel(i) << 16 | vct->MinorChannel(i);
     }
 }
 
Index: libs/libmythtv/mpeg/atscstreamdata.h
===================================================================
--- libs/libmythtv/mpeg/atscstreamdata.h	(revision 10303)
+++ libs/libmythtv/mpeg/atscstreamdata.h	(working copy)
@@ -38,8 +38,8 @@
     /// Current UTC to GPS time offset in seconds
     uint GPSOffset(void) const { return _GPS_UTC_offset; }
 
-    inline uint GetATSCSRCID(uint eit_sourceid) const;
-    inline bool HasATSCSRCIDMap(void) const;
+    inline uint GetATSCMajorMinor(uint eit_sourceid) const;
+    inline bool HasATSCMajorMinorMap(void) const;
     bool HasEITPIDChanges(const uint_vec_t &in_use_pid) const;
     bool GetEITPIDChanges(const uint_vec_t &in_use_pid,
                           uint_vec_t &pids_to_add,
@@ -120,7 +120,7 @@
     atsc_eit_pid_map_t        _atsc_eit_pids;
     atsc_ett_pid_map_t        _atsc_ett_pids;
 
-    QMap<uint,uint>           _sourceid_to_atscsrcid;
+    QMap<uint,uint>           _sourceid_to_atsc_maj_min;
 
 
     // Signals
@@ -146,16 +146,16 @@
 };
 
 
-inline uint ATSCStreamData::GetATSCSRCID(uint eit_sourceid) const
+inline uint ATSCStreamData::GetATSCMajorMinor(uint eit_sourceid) const
 {
     QMutexLocker locker(&_listener_lock);
-    return _sourceid_to_atscsrcid[eit_sourceid];
+    return _sourceid_to_atsc_maj_min[eit_sourceid];
 }
 
-inline bool ATSCStreamData::HasATSCSRCIDMap(void) const
+inline bool ATSCStreamData::HasATSCMajorMinorMap(void) const
 {
     QMutexLocker locker(&_listener_lock);
-    return _sourceid_to_atscsrcid.size();
+    return !_sourceid_to_atsc_maj_min.empty();
 }
 
 inline int ATSCStreamData::VersionTVCT(uint tsid) const
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
--- libs/libmythtv/dvbchannel.cpp	(revision 10303)
+++ libs/libmythtv/dvbchannel.cpp	(working copy)
@@ -52,6 +52,7 @@
 #include "mythdbcon.h"
 #include "tv_rec.h"
 #include "cardutil.h"
+#include "channelutil.h"
 
 #include "dvbtypes.h"
 #include "dvbchannel.h"
@@ -242,41 +243,53 @@
     return true;
 }
 
-bool DVBChannel::SetChannelByString(const QString &chan)
+bool DVBChannel::SetChannelByString(const QString &channum)
 {
-    QString func = QString("SetChannelByString(%1)").arg(chan);
-    VERBOSE(VB_CHANNEL, LOC + func);
+    QString tmp     = QString("SetChannelByString(%1): ").arg(channum);
+    QString loc     = LOC + tmp;
+    QString loc_err = LOC_ERR + tmp;
+
+    VERBOSE(VB_CHANNEL, loc);
     if (fd_frontend < 0)
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + func + QString(": not open"));
+        VERBOSE(VB_IMPORTANT, loc_err + "Channel object "
+                "will not open, can not change channels.");
 
         return false;
     }
 
-    if (curchannelname == chan && !first_tune)
+    if (curchannelname == channum && !first_tune)
     {
-        VERBOSE(VB_CHANNEL, LOC + func + ": already on channel");
+        VERBOSE(VB_CHANNEL, loc + "Already on channel");
         return true;
     }
 
     QString inputName;
-    if (!CheckChannel(chan, inputName))
+    if (!CheckChannel(channum, inputName))
     {
-        VERBOSE(VB_IMPORTANT, LOC + "CheckChannel failed. " +
-                QString("Please verify channel '%1'").arg(chan) +
-                " in the \"mythtv-setup\" Channel Editor.");
+        VERBOSE(VB_IMPORTANT, loc_err +
+                "CheckChannel failed. Please verify the channel "
+                "in the 'mythtv-setup' Channel Editor.");
+
         return false;
     }
-    // If CheckChannel filled in the inputName we need to
-    // change inputs.
-    if (!inputName.isEmpty())
+
+    // If CheckChannel filled in the inputName we need to change inputs.
+    if (!inputName.isEmpty() && (nextInputID == currentInputID))
         nextInputID = GetInputByName(inputName);
-    
-    if (GetChannelOptions(chan) == false)
+
+    // Get the input data for the channel
+    int inputid = (nextInputID >= 0) ? nextInputID : currentInputID;
+    InputMap::const_iterator it = inputs.find(inputid);
+    if (it == inputs.end())
+        return false;
+
+    // Initialize all the tuning parameters
+    if (!InitChannelParams((*it)->sourceid, channum))
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to get channel options for " +
-                QString("channel '%1'.").arg(chan));
-        
+        VERBOSE(VB_IMPORTANT, loc_err +
+                "Failed to initialize channel options");
+
         return false;
     }
 
@@ -285,19 +298,17 @@
 
     if (!Tune(cur_tuning))
     {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + "Tuning to frequency for " +
-                QString("channel '%1'.").arg(chan));
+        VERBOSE(VB_IMPORTANT, loc_err + "Tuning to frequency.");
 
         return false;
     }
 
-    curchannelname = chan;
+    curchannelname = QDeepCopy<QString>(channum);
 
-    VERBOSE(VB_CHANNEL, LOC + "Tuned to frequency for " +
-            QString("channel '%1'.").arg(chan));
+    VERBOSE(VB_CHANNEL, loc + "Tuned to frequency.");
 
     currentInputID = nextInputID;
-    inputs[currentInputID]->startChanNum = curchannelname;
+    inputs[currentInputID]->startChanNum = QDeepCopy<QString>(curchannelname);
 
     return true;
 }
@@ -333,58 +344,36 @@
     return SetChannelByString((*it)->startChanNum);
 }
 
-/** \fn DVBChannel::GetChannelOptions(const QString &)
- *  \brief This function called when tuning to a specific stream.
+/** \fn DVBChannel::InitChannelParams(uint,const QString&)
+ *  \brief Initializes all variables pertaining to a channel.
+ *
+ *  \sa GetTransportOptions(int) which this calls to initialize
+ *         variables required to initially tune to the
+ *         transport where the channel may be found.
+ *
+ *  \return true on success and false on failure
  */
-bool DVBChannel::GetChannelOptions(const QString &channum)
+bool DVBChannel::InitChannelParams(uint sourceid, const QString &channum)
 {
-    // Reset Channel data
-    currentATSCMajorChannel = currentATSCMinorChannel = -1;
-    currentProgramNum = -1;
-    currentOriginalNetworkID = currentTransportID = -1;
+    QString tvformat, modulation, freqtable, freqid;
+    int finetune;
+    uint64_t frequency;
+    uint mplexid;
 
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare(
-        "SELECT chanid, serviceid, channel.mplexid, atscsrcid, "
-        "       cardinputid, networkid, transportid "
-        "FROM channel, cardinput, capturecard, dtv_multiplex "
-        "WHERE channel.mplexid    = dtv_multiplex.mplexid AND "
-        "      cardinput.sourceid = channel.sourceid      AND "
-        "      capturecard.cardid = cardinput.cardid      AND "
-        "      cardinput.cardid   = :CARDID               AND "
-        "      channel.channum    = :CHANNUM");
-    query.bindValue(":CARDID",  GetCardID());
-    query.bindValue(":CHANNUM", channum);
-
-    if (!query.exec() || !query.isActive())
+    if (!ChannelUtil::GetChannelData(
+            sourceid,   channum,
+            tvformat,   modulation,   freqtable,   freqid,
+            finetune,   frequency,    currentProgramNum,
+            currentATSCMajorChannel,  currentATSCMinorChannel,
+            currentTransportID,       currentOriginalNetworkID,
+            mplexid,    commfree))
     {
-        MythContext::DBError("GetChannelOptions - ChanID", query);
         return false;
     }
 
-    uint mplexid = 0;
-    while (query.next() && !mplexid)
-    {
-        if (query.value(4).toInt() != nextInputID)
-            continue;
+    if (currentATSCMinorChannel)
+        currentProgramNum = -1;
 
-        currentProgramNum = query.value(1).toUInt();
-        mplexid           = query.value(2).toUInt();
-
-        if (query.value(3).toUInt() & 0xff)
-        {
-            currentATSCMajorChannel  = query.value(3).toUInt() >> 8;
-            currentATSCMinorChannel  = query.value(3).toUInt() & 0xff;
-            currentTransportID       = query.value(6).toUInt();
-            currentProgramNum        = -1;
-        }
-        else if (query.value(5).toUInt() > 0)
-        {
-            currentOriginalNetworkID = query.value(5).toUInt();
-            currentTransportID       = query.value(6).toUInt();
-        }
-    }
-
     if (mplexid)
         return GetTransportOptions(mplexid);
 
@@ -395,8 +384,6 @@
 /** \fn DVBChannel::GetTransportOptions(int mplexid)
  *  \brief Initializes tuning from database using mplexid.
  *
- *  \todo pParent doesn't exist when you create a DVBChannel from videosource
- *        but this is important (i think) for remote backends
  *  \return true on success and false on failure
  */
 bool DVBChannel::GetTransportOptions(int mplexid)
Index: libs/libmythtv/videosource.cpp
===================================================================
--- libs/libmythtv/videosource.cpp	(revision 10303)
+++ libs/libmythtv/videosource.cpp	(working copy)
@@ -29,6 +29,7 @@
 #include "scanwizard.h"
 #include "cardutil.h"
 #include "sourceutil.h"
+#include "channelutil.h"
 #include "frequencies.h"
 
 #ifdef USING_DVB
@@ -1614,34 +1615,24 @@
     else if (query.next())
         startChan = query.value(0).toString();
 
-    // Get the existing channels on the connected source
-    query.prepare(
-        "SELECT channum "
-        "FROM channel "
-        "WHERE sourceid = :SOURCEID "
-        "ORDER BY atscsrcid, channum");
-    query.bindValue(":SOURCEID", sourceid.toUInt());
+    DBChanList channels = ChannelUtil::GetChannels(sourceid.toUInt(), false);
 
-    QString nnsc = startChan.isEmpty() ? "" : startChan;
-    if (!query.exec() || !query.isActive())
+    if (channels.empty())
     {
-        addSelection(tr("DB Error, see console"), nnsc);
-        MythContext::DBError("SetSourceID -- get channels", query);
+        addSelection(tr("Please add channels to this source"),
+                     startChan.isEmpty() ? "" : startChan);
+        return;
     }
-    else if (query.size() > 0)
+
+    // If there are channels sort them, then add them 
+    // (selecting the old start channel if it is there).
+    QString order = gContext->GetSetting("ChannelOrdering", "channum");
+    ChannelUtil::SortChannels(channels, order);
+    for (uint i = 0; i < channels.size(); i++)
     {
-        // If there are channels add them, and
-        // highlight the old start channel
-        while (query.next())
-        {
-            const QString channum = query.value(0).toString();
-            addSelection(channum, channum, channum == startChan);
-        }
+        const QString channum = channels[i].channum;
+        addSelection(channum, channum, channum == startChan);
     }
-    else
-    {
-        addSelection(tr("Please add channels to this source"), nnsc);
-    }
 }
 
 class InputPriority: public SpinBoxSetting, public CISetting {
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 10303)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -1069,12 +1069,6 @@
         channel->SetChannelByString(startchannel);
     else
         channel->SwitchToInput(inputname, startchannel);
-
-    // Set channel ordering, and check validity...
-    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
-    ChannelUtil::GetNextChannel(cardid, inputname, startchannel,
-                                BROWSE_SAME, chanorder);
-    channel->SetChannelOrdering(chanorder);
 }
 
 void TVRec::CloseChannel(void)
@@ -2815,32 +2809,24 @@
 {
     QString compare     = "<=";
     QString sortorder   = "desc";
-    QString input       = channel->GetCurrentInput();
-    QString order       = channel->GetOrdering();
-    int     chanid      = -1;
+    uint     chanid     = 0;
 
     if (BROWSE_SAME == direction)
-        chanid = ChannelUtil::GetNextChannel(
-            cardid, input, channum, CHANNEL_DIRECTION_SAME, order);
+        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME);
     else if (BROWSE_UP == direction)
-        chanid = ChannelUtil::GetNextChannel(
-            cardid, input, channum, CHANNEL_DIRECTION_UP, order);
+        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_UP);
     else if (BROWSE_DOWN == direction)
-        chanid = ChannelUtil::GetNextChannel(
-            cardid, input, channum, CHANNEL_DIRECTION_DOWN, order);
+        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_DOWN);
     else if (BROWSE_FAVORITE == direction)
-        chanid = ChannelUtil::GetNextChannel(
-            cardid, input, channum, CHANNEL_DIRECTION_FAVORITE, order);
+        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_FAVORITE);
     else if (BROWSE_LEFT == direction)
     {
-        chanid = ChannelUtil::GetNextChannel(
-            cardid, input, channum, CHANNEL_DIRECTION_SAME, order);
+        chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME);
         compare = "<";
     }
     else if (BROWSE_RIGHT == direction)
     {
-	chanid = ChannelUtil::GetNextChannel(
-            cardid, input, channum, CHANNEL_DIRECTION_SAME, order);
+	chanid = channel->GetNextChannel(channum, CHANNEL_DIRECTION_SAME);
         compare = ">";
         sortorder = "asc";
     }
@@ -3047,13 +3033,9 @@
 
     if (channel && !channum.isEmpty() && (channum.find("NextChannel") >= 0))
     {
-        int dir = channum.right(channum.length() - 12).toInt();
-        uint chanid;
-        QString channelordering = channel->GetOrdering();
-        channum = ChannelUtil::GetNextChannel(
-            cardid,                    channel->GetCurrentInput(),
-            channel->GetCurrentName(), dir,
-            channelordering,           chanid);
+        int dir     = channum.right(channum.length() - 12).toInt();
+        uint chanid = channel->GetNextChannel(0, dir);
+        channum     = ChannelUtil::GetChanNum(chanid);
     }
 
     return channum;
@@ -3081,9 +3063,8 @@
 
         if (atsc)
         {
-            uint atscsrcid = ChannelUtil::GetATSCSRCID(sourceid, newchannum);
-            uint major = atscsrcid >> 8;
-            uint minor = atscsrcid & 0xff;
+            uint major, minor = 0;
+            ChannelUtil::GetATSCChannel(sourceid, newchannum, major, minor);
 
             if (minor && atsc->HasChannel(major, minor))
             {
Index: libs/libmythtv/programinfo.cpp
===================================================================
--- libs/libmythtv/programinfo.cpp	(revision 10303)
+++ libs/libmythtv/programinfo.cpp	(working copy)
@@ -4002,8 +4002,7 @@
         querystr += " GROUP BY program.starttime, channel.channum, "
             "  channel.callsign, program.title ";
     if (!sql.contains(" ORDER BY "))
-        querystr += QString(" ORDER BY program.starttime, ") + 
-                    gContext->GetSetting("ChannelOrdering", "channum+0") + " ";
+        querystr += " ORDER BY program.starttime, program.chanid ";
     if (!sql.contains(" LIMIT "))
         querystr += " LIMIT 1000 ";
 
@@ -4096,7 +4095,6 @@
 
     QString ip        = gContext->GetSetting("BackendServerIP");
     QString port      = gContext->GetSetting("BackendServerPort");
-    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
 
     // ----------------------------------------------------------------------
 
@@ -4134,38 +4132,49 @@
 
     // ----------------------------------------------------------------------
 
-    QString thequery = "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
-                       "recorded.title,recorded.subtitle,recorded.description,"
-                       "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
-                       "recorded.autoexpire,editing,bookmark,recorded.category,"
-                       "recorded.recgroup,record.dupin,record.dupmethod,"
-                       "record.recordid,outputfilters,"
-                       "recorded.seriesid,recorded.programid,recorded.filesize, "
-                       "recorded.lastmodified, recorded.findid, "
-                       "recorded.originalairdate, recorded.playgroup, "
-                       "recorded.basename, recorded.progstart, "
-                       "recorded.progend, recorded.stars, "
-                       "recordedprogram.stereo, recordedprogram.hdtv, "
-                       "recordedprogram.closecaptioned "
-                       "FROM recorded "
-                       "LEFT JOIN record ON recorded.recordid = record.recordid "
-                       "LEFT JOIN channel ON recorded.chanid = channel.chanid "
-                       "LEFT JOIN recordedprogram ON (recorded.chanid = recordedprogram.chanid "
-                              "AND recorded.starttime = recordedprogram.starttime) "
-                       "WHERE (recorded.deletepending = 0 OR "
-                              "DATE_ADD(recorded.lastmodified, "
-                                       "INTERVAL 5 MINUTE) <= NOW()) "
-                       "ORDER BY recorded.starttime";
+    QString thequery =
+        "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
+        "recorded.title,recorded.subtitle,recorded.description,"
+        "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
+        "recorded.autoexpire,editing,bookmark,recorded.category,"
+        "recorded.recgroup,record.dupin,record.dupmethod,"
+        "record.recordid,outputfilters,"
+        "recorded.seriesid,recorded.programid,recorded.filesize, "
+        "recorded.lastmodified, recorded.findid, "
+        "recorded.originalairdate, recorded.playgroup, "
+        "recorded.basename, recorded.progstart, "
+        "recorded.progend, recorded.stars, "
+        "recordedprogram.stereo, recordedprogram.hdtv, "
+        "recordedprogram.closecaptioned "
+        "FROM recorded "
+        "LEFT JOIN record ON recorded.recordid = record.recordid "
+        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
+        "LEFT JOIN recordedprogram ON "
+        " ( recorded.chanid    = recordedprogram.chanid AND "
+        "   recorded.starttime = recordedprogram.starttime ) "
+        "WHERE ( recorded.deletepending = 0 OR "
+        "        DATE_ADD(recorded.lastmodified,  INTERVAL 5 MINUTE) <= NOW() "
+        "      ) "
+        "ORDER BY recorded.starttime";
 
     if ( bDescending )
         thequery += " DESC";
 
-    thequery += ", " + chanorder + " DESC;";
+    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum");
+    if (chanorder.left(5) != "smart")
+        thequery += ", " + chanorder + " DESC;";
+    else // approximation which the DB can handle
+        thequery += ",atsc_major_chan,atsc_minor_chan,channum,callsign DESC;";
 
     query.prepare(thequery);
 
-    if (query.exec() && query.isActive() && query.size() > 0)
+    if (!query.exec() || !query.isActive())
     {
+        MythContext::DBError("ProgramList::FromRecorded", query);
+        return true;
+    }
+    else
+    {
         while (query.next())
         {
             ProgramInfo *proginfo = new ProgramInfo;
Index: libs/libmythtv/eitscanner.cpp
===================================================================
--- libs/libmythtv/eitscanner.cpp	(revision 10303)
+++ libs/libmythtv/eitscanner.cpp	(working copy)
@@ -232,7 +232,8 @@
             "      channum             != ''               AND "
             "      cardinput.cardid     = :CARDID "
             "GROUP BY mplexid "
-            "ORDER BY cardinput.sourceid, atscsrcid, mplexid");
+            "ORDER BY cardinput.sourceid, mplexid, "
+            "         atsc_major_chan, atsc_minor_chan ");
         query.bindValue(":CARDID", rec->GetCaptureCardNum());
 
         if (!query.exec() || !query.isActive())
Index: libs/libmythtv/channel.cpp
===================================================================
--- libs/libmythtv/channel.cpp	(revision 10303)
+++ libs/libmythtv/channel.cpp	(working copy)
@@ -411,25 +411,23 @@
     return finished;
 }
 
-bool Channel::SetChannelByString(const QString &chan)
+bool Channel::SetChannelByString(const QString &channum)
 {
-    VERBOSE(VB_CHANNEL, QString("Channel(%1)::SetChannelByString(%2)")
-            .arg(device).arg(chan));
+    QString loc = LOC + QString("SetChannelByString(%1)").arg(channum);
+    VERBOSE(VB_CHANNEL, loc);
     
     if (!Open())
     {
-        VERBOSE(VB_IMPORTANT, QString(
-                    "Channel(%1)::SetChannelByString(): Channel object "
-                    "wasn't open, can't change channels").arg(device));
+        VERBOSE(VB_IMPORTANT, loc + "Error, Channel object will not open, "
+                "can not change channels.");
         return false;
     }
 
     QString inputName;
-    if (!CheckChannel(chan, inputName))
+    if (!CheckChannel(channum, inputName))
     {
-        VERBOSE(VB_IMPORTANT, LOC + "CheckChannel failed. " +
-                QString("Please verify channel '%1'").arg(chan) +
-                " in the \"mythtv-setup\" Channel Editor.");
+        VERBOSE(VB_IMPORTANT, loc + "CheckChannel failed. Please verify " +
+                "the channel in the 'mythtv-setup' Channel Editor.");
         return false;
     }
 
@@ -437,7 +435,7 @@
     // change inputs and return, since the act of changing
     // inputs will change the channel as well.
     if (!inputName.isEmpty())
-        return ChannelBase::SwitchToInput(inputName, chan);
+        return ChannelBase::SwitchToInput(inputName, channum);
 
     SetCachedATSCInfo("");
 
@@ -445,41 +443,25 @@
     if (it == inputs.end())
         return false;
 
-    MSqlQuery query(MSqlQuery::InitCon());
-    QString thequery = QString(
-        "SELECT finetune, freqid, tvformat, freqtable, "
-        "       atscsrcid, commfree, mplexid "
-        "FROM channel, videosource "
-        "WHERE videosource.sourceid = channel.sourceid AND "
-        "      channum = '%1' AND channel.sourceid = '%2'")
-        .arg(chan).arg((*it)->sourceid);
+    // Fetch tuning data from the database.
+    QString tvformat, modulation, freqtable, freqid;
+    int finetune;
+    uint64_t frequency;
+    int mpeg_prog_num;
+    uint atsc_major, atsc_minor, mplexid, tsid, netid;
 
-    query.prepare(thequery);
-
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("fetchtuningparams", query);
-    if (query.size() <= 0)
+    if (!ChannelUtil::GetChannelData(
+        (*it)->sourceid, channum,
+        tvformat, modulation, freqtable, freqid,
+        finetune, frequency,
+        mpeg_prog_num, atsc_major, atsc_minor, tsid, netid,
+        mplexid, commfree))
     {
-        VERBOSE(VB_IMPORTANT, QString(
-                    "Channel(%1): CheckChannel failed because it could not\n"
-                    "\t\t\tfind channel number '%2' in DB for source '%3'.")
-                .arg(device).arg(chan).arg((*it)->sourceid));
         return false;
     }
-    query.next();
 
-    int finetune      = query.value(0).toInt();
-    QString freqid    = query.value(1).toString();
-    QString tvformat  = query.value(2).toString();
-    QString freqtable = query.value(3).toString();
-    uint atscsrcid    = query.value(4).toInt();
-    commfree          = query.value(5).toBool();
-    uint mplexid      = query.value(6).toInt();
-
-    QString modulation;
-    int frequency = ChannelUtil::GetTuningParams(mplexid, modulation);
+    // If the frequency is zeroed out, don't use it directly.
     bool ok = (frequency > 0);
-
     if (!ok)
     {
         frequency = (freqid.toInt(&ok) + finetune) * 1000;
@@ -487,26 +469,25 @@
     }
     bool isFrequency = ok && (frequency > 10000000);
 
+    // If we are tuning to a freqid, rather than an actual frequency,
+    // we need to set the frequency table to use.
     if (!isFrequency)
     {
-        if (freqtable == "default" || freqtable.isNull() || freqtable.isEmpty())
+        if (freqtable == "default" || freqtable.isEmpty())
             SetFreqTable(defaultFreqTable);
         else
             SetFreqTable(freqtable);
     }
 
+    // Set NTSC, PAL, ATSC, etc.
     SetFormat(tvformat);
 
-    curchannelname = chan;
-
+    // Setup filters & recording picture attributes for framegrabing recorders.
     if (pParent)
-        pParent->SetVideoFiltersForChannel(GetCurrentSourceID(), chan);
-
+        pParent->SetVideoFiltersForChannel(GetCurrentSourceID(), channum);
     InitPictureAttributes();
 
-    inputs[currentInputID]->startChanNum = curchannelname;
-
-    // Tune
+    // Tune to proper frequency
     if ((*it)->externalChanger.isEmpty())
     {
         if (isFrequency)
@@ -523,13 +504,18 @@
     else if (!ChangeExternalChannel(freqid))
         return false;
 
-    QString min_maj = QString("%1_0").arg(chan);
-    if (atscsrcid > 255)
-        min_maj = QString("%1_%2")
-            .arg(atscsrcid >> 8).arg(atscsrcid & 0xff);
+    // Set the current channum to the new channel's channum
+    curchannelname = QDeepCopy<QString>(channum);
 
-    SetCachedATSCInfo(min_maj);
+    // Set the major and minor channel for any additional multiplex tuning
+    if (atsc_major || atsc_minor)
+        SetCachedATSCInfo(QString("%1_%2").arg(atsc_major).arg(atsc_minor));
+    else
+        SetCachedATSCInfo(QString("%1_0").arg(channum));
 
+    // Set this as the future start channel for this source
+    inputs[currentInputID]->startChanNum = curchannelname;
+
     return true;
 }
 
Index: programs/mythfrontend/globalsettings.cpp
===================================================================
--- programs/mythfrontend/globalsettings.cpp	(revision 10303)
+++ programs/mythfrontend/globalsettings.cpp	(working copy)
@@ -983,11 +983,8 @@
 {
     HostComboBox *gc = new HostComboBox("ChannelOrdering");
     gc->setLabel(QObject::tr("Channel ordering"));
-    gc->addSelection(QObject::tr("channel number (numeric)"), "channum + 0");
-    gc->addSelection(QObject::tr("channel number (alpha)"), "channum");
-    gc->addSelection(QObject::tr("database order"), "chanid");
-    gc->addSelection(QObject::tr("channel name"), "callsign");
-    gc->addSelection(QObject::tr("ATSC channel"), "atscsrcid");
+    gc->addSelection(QObject::tr("channel number"), "channum");
+    gc->addSelection(QObject::tr("channel name"),   "callsign");
     return gc;
 }
 
Index: programs/mythfrontend/manualschedule.cpp
===================================================================
--- programs/mythfrontend/manualschedule.cpp	(revision 10303)
+++ programs/mythfrontend/manualschedule.cpp	(working copy)
@@ -34,6 +34,7 @@
 #include "libmythtv/scheduledrecording.h"
 #include "libmythtv/recordingtypes.h"
 #include "libmythtv/remoteutil.h"
+#include "libmythtv/channelutil.h"
 
 ManualSchedule::ManualSchedule(MythMainWindow *parent, const char *name)
               : MythDialog(parent, name)
@@ -72,26 +73,22 @@
     m_channel->setBackgroundOrigin(WindowOrigin);
 
 
-    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
+    QString longChannelFormat = gContext->GetSetting("LongChannelFormat",
+                                                     "<num> <name>");
+    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum");
+    DBChanList channels = ChannelUtil::GetChannels(0, false, "callsign");
+    ChannelUtil::SortChannels(channels, chanorder);
 
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare(QString("SELECT chanid, channum, callsign, name "
-                          "FROM channel GROUP BY channum, callsign "
-                          "ORDER BY %1;").arg(chanorder));
+    for (uint i = 0; i < channels.size(); i++)
+    {
+        QString chantext = QDeepCopy<QString>(longChannelFormat);
+        chantext
+            .replace("<num>",  channels[i].channum)
+            .replace("<sign>", channels[i].callsign)
+            .replace("<name>", channels[i].name);
 
-    QString longChannelFormat = 
-        gContext->GetSetting("LongChannelFormat", "<num> <name>");
-
-    if (query.exec() && query.isActive() && query.size()) {
-      while(query.next()) {
-          QString channel = longChannelFormat;
-          channel.replace("<num>", query.value(1).toString())
-              .replace("<sign>", QString::fromUtf8(query.value(2).toString()))
-              .replace("<name>", QString::fromUtf8(query.value(3).toString()));
-          m_channel->insertItem(channel);
-          m_chanids << query.value(0).toString();
-      }
-      
+        m_channel->insertItem(chantext);
+        m_chanids << QString::number(channels[i].chanid);
     }
 
     hbox->addWidget(m_channel);
Index: programs/mythbackend/mainserver.cpp
===================================================================
--- programs/mythbackend/mainserver.cpp	(revision 10303)
+++ programs/mythbackend/mainserver.cpp	(working copy)
@@ -987,7 +987,6 @@
 
     QString ip = gContext->GetSetting("BackendServerIP");
     QString port = gContext->GetSetting("BackendServerPort");
-    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum + 0");
 
     QMap<QString, int> inUseMap;
     QString inUseKey;
@@ -1019,34 +1018,40 @@
         }
 
 
-    QString thequery = "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
-                       "recorded.title,recorded.subtitle,recorded.description,"
-                       "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
-                       "recorded.autoexpire,editing,bookmark,recorded.category,"
-                       "recorded.recgroup,record.dupin,record.dupmethod,"
-                       "record.recordid,outputfilters,"
-                       "recorded.seriesid,recorded.programid,recorded.filesize, "
-                       "recorded.lastmodified, recorded.findid, "
-                       "recorded.originalairdate, recorded.playgroup, "
-                       "recorded.basename, recorded.progstart, "
-                       "recorded.progend, recorded.stars, "
-                       "recordedprogram.stereo, recordedprogram.hdtv, "
-                       "recordedprogram.closecaptioned, transcoded, "
-                       "recorded.recpriority "
-                       "FROM recorded "
-                       "LEFT JOIN record ON recorded.recordid = record.recordid "
-                       "LEFT JOIN channel ON recorded.chanid = channel.chanid "
-                       "LEFT JOIN recordedprogram ON (recorded.chanid = recordedprogram.chanid "
-                              "AND recorded.starttime = recordedprogram.starttime) "
-                       "WHERE (recorded.deletepending = 0 OR "
-                              "DATE_ADD(recorded.lastmodified, "
-                                       "INTERVAL 5 MINUTE) <= NOW()) "
-                       "ORDER BY recorded.starttime";
+    QString thequery =
+        "SELECT recorded.chanid,recorded.starttime,recorded.endtime,"
+        "recorded.title,recorded.subtitle,recorded.description,"
+        "recorded.hostname,channum,name,callsign,commflagged,cutlist,"
+        "recorded.autoexpire,editing,bookmark,recorded.category,"
+        "recorded.recgroup,record.dupin,record.dupmethod,"
+        "record.recordid,outputfilters,"
+        "recorded.seriesid,recorded.programid,recorded.filesize, "
+        "recorded.lastmodified, recorded.findid, "
+        "recorded.originalairdate, recorded.playgroup, "
+        "recorded.basename, recorded.progstart, "
+        "recorded.progend, recorded.stars, "
+        "recordedprogram.stereo, recordedprogram.hdtv, "
+        "recordedprogram.closecaptioned, transcoded, "
+        "recorded.recpriority "
+        "FROM recorded "
+        "LEFT JOIN record ON recorded.recordid = record.recordid "
+        "LEFT JOIN channel ON recorded.chanid = channel.chanid "
+        "LEFT JOIN recordedprogram ON "
+        " ( recorded.chanid = recordedprogram.chanid AND "
+        "  recorded.starttime = recordedprogram.starttime ) "
+        "WHERE ( recorded.deletepending = 0 OR "
+        "        DATE_ADD(recorded.lastmodified,  INTERVAL 5 MINUTE) <= NOW() "
+        "      ) "
+        "ORDER BY recorded.starttime";
 
     if (type == "Delete")
         thequery += " DESC";
 
-    thequery += ", " + chanorder + " DESC;";
+    QString chanorder = gContext->GetSetting("ChannelOrdering", "channum");
+    if (chanorder.left(5) != "smart")
+        thequery += ", " + chanorder + " DESC;";
+    else // approximation which the DB can handle
+        thequery += ",atsc_major_chan,atsc_minor_chan,channum,callsign DESC;";
 
     QStringList outputlist;
     QString fileprefix = gContext->GetFilePrefix();
@@ -1055,8 +1060,13 @@
 
     query.prepare(thequery);
 
-    if (query.exec() && query.isActive() && query.size() > 0)
+    if (!query.exec() || !query.isActive())
     {
+        MythContext::DBError("ProgramList::FromRecorded", query);
+        outputlist << "0";
+    }
+    else
+    {
         outputlist << QString::number(query.size());
 
         while (query.next())
@@ -1248,8 +1258,6 @@
             delete proginfo;
         }
     }
-    else
-        outputlist << "0";
 
     for (ri = schedList.begin(); ri != schedList.end(); ri++)
         delete (*ri);
