Index: libs/libmythtv/cardutil.h
===================================================================
--- libs/libmythtv/cardutil.h	(revision 12562)
+++ libs/libmythtv/cardutil.h	(working copy)
@@ -164,6 +164,7 @@
     static bool         IgnoreEncrypted(uint cardid, const QString &inputname);
     static bool         TVOnly(uint cardid, const QString &inputname);
     static bool         IsInNeedOfExternalInputConf(uint cardid);
+    static uint         GetQuickTuning(uint cardid, const QString &inputname);
 
     // DVB info
     static bool         IsDVB(uint cardid, const QString &_inputname);
Index: libs/libmythtv/dbcheck.cpp
===================================================================
--- libs/libmythtv/dbcheck.cpp	(revision 12562)
+++ 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 = "1175";
+const QString currentDatabaseVersion = "1176";
 
 static bool UpdateDBVersionNumber(const QString &newnumber);
 static bool performActualUpdate(const QString updates[], QString version,
@@ -2803,6 +2803,16 @@
             return false;
     }
 
+    if (dbver == "1175")
+    {
+        const QString updates[] = {
+"ALTER TABLE cardinput ADD COLUMN quicktune TINYINT NOT NULL default '0';",
+""
+};
+        if (!performActualUpdate(updates, "1176", dbver))
+            return false;
+    }
+
 //"ALTER TABLE cardinput DROP COLUMN preference;" in 0.22
 //"ALTER TABLE channel DROP COLUMN atscsrcid;" in 0.22
 //"ALTER TABLE recordedmarkup DROP COLUMN offset;" in 0.22
Index: libs/libmythtv/hdhrsignalmonitor.cpp
===================================================================
--- libs/libmythtv/hdhrsignalmonitor.cpp	(revision 12562)
+++ libs/libmythtv/hdhrsignalmonitor.cpp	(working copy)
@@ -98,6 +98,8 @@
     if (!GetStreamData())
         return false;
 
+    UpdateListeningForEIT();
+
     const QMap<uint, bool> &listening = GetStreamData()->ListeningPIDs();
 
     // PIDs that need to be added..
Index: libs/libmythtv/hdhrchannel.cpp
===================================================================
--- libs/libmythtv/hdhrchannel.cpp	(revision 12562)
+++ libs/libmythtv/hdhrchannel.cpp	(working copy)
@@ -26,6 +26,8 @@
 #include "channelutil.h"
 #include "frequencytables.h"
 
+#define DEBUG_PID_FILTERS
+
 #define LOC QString("HDHRChan(%1): ").arg(GetDevice())
 #define LOC_ERR QString("HDHRChan(%1), Error: ").arg(GetDevice())
 
@@ -83,6 +85,11 @@
     }
 }
 
+bool HDHRChannel::EnterPowerSavingMode(void)
+{
+    return QString::null != TunerSet("channel", "none", false);
+}
+
 bool HDHRChannel::FindDevice(void)
 {
     if (!_device_id)
@@ -134,7 +141,7 @@
     return true;
 }
 
-QString HDHRChannel::DeviceGet(const QString &name)
+QString HDHRChannel::DeviceGet(const QString &name, bool report_error_return)
 {
     QMutexLocker locker(&_lock);
 
@@ -152,15 +159,19 @@
         return QString::null;
     }
 
-    if (error) {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("DeviceGet(%1): %2").arg(name).arg(error));
+    if (report_error_return && error)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                QString("DeviceGet(%1): %2").arg(name).arg(error));
+
         return QString::null;
     }
 
     return QString(value);
 }
 
-QString HDHRChannel::DeviceSet(const QString &name, const QString &val)
+QString HDHRChannel::DeviceSet(const QString &name, const QString &val,
+                               bool report_error_return)
 {
     QMutexLocker locker(&_lock);
 
@@ -175,25 +186,32 @@
     if (hdhomerun_control_set(_control_socket, name, val, &value, &error) < 0)
     {
         VERBOSE(VB_IMPORTANT, LOC_ERR + "Set request failed" + ENO);
+
         return QString::null;
     }
 
-    if (error) {
-        VERBOSE(VB_IMPORTANT, LOC_ERR + QString("DeviceSet(%1 %2): %3").arg(name).arg(val).arg(error));
+    if (report_error_return && error)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR +
+                QString("DeviceSet(%1 %2): %3").arg(name).arg(val).arg(error));
+
         return QString::null;
     }
 
     return QString(value);
 }
 
-QString HDHRChannel::TunerGet(const QString &name)
+QString HDHRChannel::TunerGet(const QString &name, bool report_error_return)
 {
-    return DeviceGet(QString("/tuner%1/%2").arg(_tuner).arg(name));
+    return DeviceGet(QString("/tuner%1/%2").arg(_tuner).arg(name),
+                     report_error_return);
 }
 
-QString HDHRChannel::TunerSet(const QString &name, const QString &value)
+QString HDHRChannel::TunerSet(const QString &name, const QString &value,
+                              bool report_error_return)
 {
-    return DeviceSet(QString("/tuner%1/%2").arg(_tuner).arg(name), value);
+    return DeviceSet(QString("/tuner%1/%2").arg(_tuner).arg(name), value,
+                     report_error_return);
 }
 
 bool HDHRChannel::DeviceSetTarget(unsigned short localPort)
@@ -257,7 +275,8 @@
     if (!inputName.isEmpty())
         return SwitchToInput(inputName, channum);
 
-    SetCachedATSCInfo("");
+    ClearDTVInfo();
+    _ignore_filters = false;
 
     InputMap::const_iterator it = inputs.find(currentInputID);
     if (it == inputs.end())
@@ -312,16 +331,19 @@
     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 (mpeg_prog_num >= 0)
-        SetCachedATSCInfo(QString("0-%1").arg(mpeg_prog_num));
-    else
-        SetCachedATSCInfo(QString("%1_0").arg(channum));
+    SetDTVInfo(atsc_major, atsc_minor, netid, tsid, mpeg_prog_num);
 
     // Set this as the future start channel for this source
-    inputs[currentInputID]->startChanNum = curchannelname;
+    inputs[currentInputID]->startChanNum = QDeepCopy<QString>(curchannelname);
 
+    // Turn on the HDHomeRun program filtering if it is supported
+    // and we are tuning to an MPEG program number.
+    if (mpeg_prog_num && (GetTuningMode() == "mpeg"))
+    {
+        QString pnum = QString::number(mpeg_prog_num);
+        _ignore_filters = QString::null != TunerSet("program", pnum, false);
+    }
+
     return true;
 }
 
@@ -423,13 +445,17 @@
     it = lower_bound(_pids.begin(), _pids.end(), pid);
     if (it != _pids.end() && *it == pid)
     {
+#ifdef DEBUG_PID_FILTERS
         VERBOSE(VB_CHANNEL, "AddPID(0x"<<hex<<pid<<dec<<") NOOP");
+#endif // DEBUG_PID_FILTERS
         return true;
     }
 
     _pids.insert(it, pid);
 
+#ifdef DEBUG_PID_FILTERS
     VERBOSE(VB_CHANNEL, "AddPID(0x"<<hex<<pid<<dec<<")");
+#endif // DEBUG_PID_FILTERS
 
     if (do_update)
         return UpdateFilters();
@@ -444,18 +470,25 @@
     it = lower_bound(_pids.begin(), _pids.end(), pid);
     if (it == _pids.end())
     {
+#ifdef DEBUG_PID_FILTERS
         VERBOSE(VB_CHANNEL, "DelPID(0x"<<hex<<pid<<dec<<") NOOP");
-        return true;
+#endif // DEBUG_PID_FILTERS
+
+       return true;
     }
 
     if (*it == pid)
     {
+#ifdef DEBUG_PID_FILTERS
         VERBOSE(VB_CHANNEL, "DelPID(0x"<<hex<<pid<<dec<<") -- found");
+#endif // DEBUG_PID_FILTERS
         _pids.erase(it);
     }
     else
     {
+#ifdef DEBUG_PID_FILTERS
         VERBOSE(VB_CHANNEL, "DelPID(0x"<<hex<<pid<<dec<<") -- failed");
+#endif // DEBUG_PID_FILTERS
     }
 
     if (do_update)
@@ -467,7 +500,10 @@
 {
     QMutexLocker locker(&_lock);
 
+#ifdef DEBUG_PID_FILTERS
     VERBOSE(VB_CHANNEL, "DelAllPID()");
+#endif // DEBUG_PID_FILTERS
+
     _pids.clear();
 
     return UpdateFilters();
@@ -493,6 +529,9 @@
     vector<uint> range_min;
     vector<uint> range_max;
 
+    if (_ignore_filters)
+        return true;
+
     for (uint i = 0; i < _pids.size(); i++)
     {
         uint pid_min = _pids[i];
@@ -528,11 +567,13 @@
 
     QString new_filter = TunerSet("filter", filter);
 
+#ifdef DEBUG_PID_FILTERS
     QString msg = QString("Filter: '%1'").arg(filter);
     if (filter != new_filter)
         msg += QString("\n\t\t\t\t'%2'").arg(new_filter);
 
     VERBOSE(VB_CHANNEL, msg);
+#endif // DEBUG_PID_FILTERS
 
     return filter == new_filter;
 }
Index: libs/libmythtv/dvbchannel.h
===================================================================
--- libs/libmythtv/dvbchannel.h	(revision 12562)
+++ libs/libmythtv/dvbchannel.h	(working copy)
@@ -72,8 +72,6 @@
 
   private:
     int  GetChanID(void) const;
-    bool InitChannelParams(DTVMultiplex &t,
-                           uint sourceid, const QString &channum);
 
     void CheckOptions(DTVMultiplex &t) const;
     bool CheckModulation(DTVModulation modulation) const;
Index: libs/libmythtv/dtvchannel.h
===================================================================
--- libs/libmythtv/dtvchannel.h	(revision 12562)
+++ libs/libmythtv/dtvchannel.h	(working copy)
@@ -41,6 +41,8 @@
     virtual bool TuneMultiplex(uint mplexid, QString inputname) = 0;
     /// \brief To be used by the channel scanner and possibly the EIT scanner.
     virtual bool Tune(const DTVMultiplex &tuning, QString inputname) = 0;
+    /// \brief Enters power saving mode if the card supports it
+    virtual bool EnterPowerSavingMode(void) { return true; }
 
     // Gets
 
@@ -67,6 +69,12 @@
     /// \brief Returns PSIP table standard: MPEG, DVB, ATSC, or OpenCable
     QString GetSIStandard(void) const;
 
+    /// \brief Returns suggested tuning mode: "mpeg", "dvb", or "atsc"
+    QString GetSuggestedTuningMode(bool is_live_tv) const;
+
+    /// \brief Returns tuning mode last set by SetTuningMode().
+    QString GetTuningMode(void) const;
+
     /** \brief Returns cached MPEG PIDs for last tuned channel.
      *  \param pid_cache List of PIDs with their TableID
      *                   types is returned in pid_cache.
@@ -76,6 +84,9 @@
 
     // Sets
 
+    /// \brief Sets tuning mode: "mpeg", "dvb", "atsc", etc.
+    void SetTuningMode(const QString &tuningmode);
+
     /** \brief Saves MPEG PIDs to cache to database
      * \param pid_cache List of PIDs with their TableID types to be saved.
      */
@@ -85,7 +96,10 @@
   protected:
     /// \brief Sets PSIP table standard: MPEG, DVB, ATSC, or OpenCable
     void SetSIStandard(const QString&);
-    void SetCachedATSCInfo(const QString &chan);
+    void SetDTVInfo(uint atsc_major, uint atsc_minor,
+                    uint dvb_orig_netid,
+                    uint mpeg_tsid, int mpeg_pnum);
+    void ClearDTVInfo(void) { SetDTVInfo(0, 0, 0, 0, -1); }
 
     static void GetCachedPids(int chanid, pid_cache_t&);
     static void SaveCachedPids(int chanid, const pid_cache_t&);
@@ -94,6 +108,7 @@
     mutable QMutex dtvinfo_lock;
 
     QString sistandard; ///< PSIP table standard: MPEG, DVB, ATSC, OpenCable
+    QString tuningMode;
     int     currentProgramNum;
     uint    currentATSCMajorChannel;
     uint    currentATSCMinorChannel;
Index: libs/libmythtv/mpeg/atscstreamdata.cpp
===================================================================
--- libs/libmythtv/mpeg/atscstreamdata.cpp	(revision 12562)
+++ libs/libmythtv/mpeg/atscstreamdata.cpp	(working copy)
@@ -107,6 +107,7 @@
 
 void ATSCStreamData::Reset(int desiredProgram)
 {
+    Reset(-1,-1);
     MPEGStreamData::Reset(desiredProgram);
     AddListeningPID(ATSC_PSIP_PID);
 }
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
--- libs/libmythtv/dvbchannel.cpp	(revision 12562)
+++ libs/libmythtv/dvbchannel.cpp	(working copy)
@@ -238,6 +238,9 @@
     QString loc_err = LOC_ERR + tmp;
 
     VERBOSE(VB_CHANNEL, loc);
+
+    ClearDTVInfo();
+
     if (fd_frontend < 0)
     {
         VERBOSE(VB_IMPORTANT, loc_err + "Channel object "
@@ -272,22 +275,46 @@
     if (it == inputs.end())
         return false;
 
-    // Initialize all the tuning parameters
+    // Get the input data for the channel
+    QString tvformat, modulation, freqtable, freqid, si_std;
+    int finetune;
+    uint64_t frequency;
+    int mpeg_prog_num;
+    uint atsc_major, atsc_minor, mplexid, tsid, netid;
+
+    if (!ChannelUtil::GetChannelData(
+        (*it)->sourceid, channum,
+        tvformat, modulation, freqtable, freqid,
+        finetune, frequency,
+        si_std, mpeg_prog_num, atsc_major, atsc_minor, tsid, netid,
+        mplexid, commfree))
+    {
+        VERBOSE(VB_IMPORTANT, loc_err +
+                "Unable to find channel in database.");
+
+        return false;
+    }
+
+    // Initialize basic the tuning parameters
     DTVMultiplex tuning;
-    if (!InitChannelParams(tuning, (*it)->sourceid, channum))
+    if (!mplexid || !tuning.FillFromDB(card_type, mplexid))
     {
         VERBOSE(VB_IMPORTANT, loc_err +
-                "Failed to initialize channel options");
+                "Failed to initialize multiplex options");
 
         return false;
     }
 
+    SetDTVInfo(atsc_major, atsc_minor, netid, tsid, mpeg_prog_num);
+
+    // Try to fix any problems with the multiplex
     CheckOptions(tuning);
 
     if (!Tune(tuning, ""))
     {
         VERBOSE(VB_IMPORTANT, loc_err + "Tuning to frequency.");
 
+        ClearDTVInfo();
         return false;
     }
 
@@ -332,42 +359,6 @@
     return SetChannelByString((*it)->startChanNum);
 }
 
-/** \fn DVBChannel::InitChannelParams(DTVMultiplex&,uint,const QString&)
- *  \brief Initializes all variables pertaining to a channel.
- *
- *  \return true on success and false on failure
- */
-bool DVBChannel::InitChannelParams(DTVMultiplex  &tuning,
-                                   uint           sourceid,
-                                   const QString &channum)
-{
-    QString tvformat, modulation, freqtable, freqid, si_std;
-    int finetune;
-    uint64_t frequency;
-    uint mplexid;
-
-    if (!ChannelUtil::GetChannelData(
-            sourceid,   channum,
-            tvformat,   modulation,   freqtable,   freqid,
-            finetune,   frequency,
-            si_std,                   currentProgramNum,
-            currentATSCMajorChannel,  currentATSCMinorChannel,
-            currentTransportID,       currentOriginalNetworkID,
-            mplexid,    commfree))
-    {
-        return false;
-    }
-
-    if (currentATSCMinorChannel)
-        currentProgramNum = -1;
-
-    if (mplexid)
-        return tuning.FillFromDB(card_type, mplexid);
-
-    VERBOSE(VB_IMPORTANT, LOC_ERR + "Unable to find channel in database.");
-    return false;
-}
-
 /** \fn DVBChannel::CheckOptions(DTVMultiplex&) const
  *  \brief Checks tuning for problems, and tries to fix them.
  */
Index: libs/libmythtv/cardutil.cpp
===================================================================
--- libs/libmythtv/cardutil.cpp	(revision 12562)
+++ libs/libmythtv/cardutil.cpp	(working copy)
@@ -448,6 +448,27 @@
     return needsConf;
 }
 
+uint CardUtil::GetQuickTuning(uint cardid, const QString &input_name)
+{
+    uint quicktune = 0;
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare(
+        "SELECT quicktune "
+        "FROM cardinput "
+        "WHERE cardid    = :CARDID AND "
+        "      inputname = :INPUTNAME");
+    query.bindValue(":CARDID",    cardid);
+    query.bindValue(":INPUTNAME", input_name);
+
+    if (!query.exec() || !query.isActive())
+        MythContext::DBError("CardUtil::GetQuickTuning()", query);
+    else if (query.next())
+        quicktune = query.value(0).toUInt();
+
+    return quicktune;
+}
+
 bool CardUtil::hasV4L2(int videofd)
 {
     (void) videofd;
Index: libs/libmythtv/videosource.cpp
===================================================================
--- libs/libmythtv/videosource.cpp	(revision 12562)
+++ libs/libmythtv/videosource.cpp	(working copy)
@@ -1569,6 +1569,24 @@
     };
 };
 
+class QuickTune : public ComboBoxSetting, public CardInputDBStorage
+{
+  public:
+    QuickTune(const CardInput &parent) :
+        ComboBoxSetting(this), CardInputDBStorage(this, parent, "quicktune")
+    {
+        setLabel(QObject::tr("Use quick tuning"));
+        addSelection(QObject::tr("Never"),        "0", true);
+        //addSelection(QObject::tr("Live TV only"), "1", true);
+        addSelection(QObject::tr("Always"),       "2", false);
+        setHelpText(QObject::tr(
+                        "If enabled MythTV will tune using only the "
+                        "MPEG program number. The program numbers "
+                        "change more often than DVB or ATSC tuning "
+                        "parameters, so this is slightly less reliable."));
+    };
+};
+
 class ExternalChannelCommand :
     public LineEditSetting, public CardInputDBStorage
 {
@@ -1708,7 +1726,8 @@
     group->addChild(ci);
     group->addChild(new InputDisplayName(*this));
     group->addChild(sourceid);
-    if (!isDVBcard)
+
+    if (!isDTVcard)
     {
         group->addChild(new ExternalChannelCommand(*this));
         group->addChild(new PresetTuner(*this));
@@ -1718,7 +1737,8 @@
     {
         // we place this in a group just so the margins match the DVB ones.
         ConfigurationGroup *chgroup = 
-            new HorizontalConfigurationGroup(false, false, true, true);
+            new VerticalConfigurationGroup(false, false, true, true);
+        chgroup->addChild(new QuickTune(*this));
         chgroup->addChild(new FreeToAir(*this));
         group->addChild(chgroup);
     }
Index: libs/libmythtv/iptvchannel.cpp
===================================================================
--- libs/libmythtv/iptvchannel.cpp	(revision 12562)
+++ libs/libmythtv/iptvchannel.cpp	(working copy)
@@ -129,10 +129,14 @@
         return false;
     }
 
-    // Set the channel..
-    curchannelname = channum;
-    currentProgramNum = 1;
+    // Set the current channum to the new channel's channum
+    curchannelname = QDeepCopy<QString>(channum);
 
+    // Set the dtv channel info for any additional multiplex tuning
+    SetDTVInfo(/*atsc_major*/ 0, /*atsc_minor*/ 0,
+               /*netid*/ 0,
+               /*tsid*/ 0, /*mpeg_prog_num*/ 1);
+
     VERBOSE(VB_CHANNEL, LOC + "SetChannelByString() -- end");
     return true;
 }
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 12562)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -774,7 +774,8 @@
     changeState = false;
 
     eitScanStartTime = QDateTime::currentDateTime();    
-    if ((internalState == kState_None) && (genOpt.cardtype == "DVB"))
+    if ((internalState == kState_None) &&
+        CardUtil::IsEITCapable(genOpt.cardtype))
     {
         // Add some randomness to avoid all cards starting
         // EIT scanning at nearly the same time.
@@ -998,8 +999,11 @@
     MythEvent me("RECORDING_LIST_CHANGE");
     gContext->dispatch(me);
     pauseNotify = true;
-}    
 
+    if (GetDTVChannel())
+        GetDTVChannel()->EnterPowerSavingMode();
+}
+
 DVBRecorder *TVRec::GetDVBRecorder(void)
 {
 #ifdef USING_DVB
@@ -1071,6 +1075,9 @@
         }
         VERBOSE(VB_IMPORTANT, LOC_ERR + msg1 + "\n\t\t\t" + msg2);
     }
+
+    if (GetDTVChannel())
+        GetDTVChannel()->EnterPowerSavingMode();
 }
 
 void TVRec::CloseChannel(void)
@@ -1668,12 +1675,25 @@
         sd->SetCaching(true);
     }
 
-    QString sistandard = dtvchan->GetSIStandard();
+    uint neededVideo = 0;
+    uint neededAudio = 0;
 
+    ProgramInfo *rec = lastTuningRequest.program;
+    RecordingProfile profile;
+    load_profile(genOpt.cardtype, tvchain, rec, profile);
+    const Setting *setting = profile.byName("recordingtype");
+    if (setting)
+    {
+        neededVideo = (setting->getValue() == "tv") ? 1 : 0;
+        neededAudio = (setting->getValue() == "audio") ? 1 : 0;
+    }
+
+    const QString tuningmode = dtvchan->GetTuningMode();
+
     // Check if this is an ATSC Channel
     int major = dtvchan->GetMajorChannel();
     int minor = dtvchan->GetMinorChannel();
-    if ((minor > 0) && (sistandard == "atsc"))
+    if ((minor > 0) && (tuningmode == "atsc"))
     {
         QString msg = QString("ATSC channel: %1_%2").arg(major).arg(minor);
         VERBOSE(VB_RECORD, LOC + msg);
@@ -1690,7 +1710,8 @@
         asd->Reset(major, minor);
         sm->SetStreamData(sd);
         sm->SetChannel(major, minor);
-        sd->SetVideoStreamsRequired(1);
+        sd->SetVideoStreamsRequired(neededVideo);
+        sd->SetAudioStreamsRequired(neededAudio);
 
         // Try to get pid of VCT from cache and
         // require MGT if we don't have VCT pid.
@@ -1704,14 +1725,11 @@
     // Check if this is an DVB channel
     int progNum = dtvchan->GetProgramNumber();
 #ifdef USING_DVB
-    if ((progNum >= 0) && (sistandard == "dvb"))
+    if ((progNum >= 0) && (tuningmode == "dvb"))
     {
         int netid   = dtvchan->GetOriginalNetworkID();
         int tsid    = dtvchan->GetTransportID();
 
-        uint neededVideo = 0;
-        uint neededAudio = 0;
-
         DVBStreamData *dsd = dynamic_cast<DVBStreamData*>(sd);
         if (!dsd)
         {
@@ -1721,16 +1739,6 @@
                 GetDTVRecorder()->SetStreamData(dsd);
         }
 
-        ProgramInfo *rec = lastTuningRequest.program;
-        RecordingProfile profile;
-        load_profile(genOpt.cardtype, tvchain, rec, profile);
-        const Setting *setting = profile.byName("recordingtype");
-        if (setting)
-        {
-            neededVideo = (setting->getValue() == "tv") ? 1 : 0;
-            neededAudio = (setting->getValue() == "audio") ? 1 : 0;
-        }
-
         VERBOSE(VB_RECORD, LOC +
                 QString("DVB service_id %1 on net_id %2 tsid %3")
                 .arg(progNum).arg(netid).arg(tsid));
@@ -1782,7 +1790,9 @@
         sd->Reset(progNum);
         sm->SetStreamData(sd);
         sm->SetProgramNumber(progNum);
-        sd->SetVideoStreamsRequired(1);
+        sd->SetVideoStreamsRequired(neededVideo);
+        sd->SetAudioStreamsRequired(neededAudio);
+
         sm->AddFlags(SignalMonitor::kDTVSigMon_WaitForPAT |
                      SignalMonitor::kDTVSigMon_WaitForPMT |
                      SignalMonitor::kDVBSigMon_WaitForPos);
@@ -1793,7 +1803,7 @@
     }
 
     QString msg = "No valid DTV info, ATSC maj(%1) min(%2), MPEG pn(%3)";
-    VERBOSE(VB_RECORD, LOC_ERR + msg.arg(major).arg(minor).arg(progNum));
+    VERBOSE(VB_IMPORTANT, LOC_ERR + msg.arg(major).arg(minor).arg(progNum));
     return false;
 }
 
@@ -2321,12 +2331,10 @@
     long long bitrate;
     if (genOpt.cardtype == "MPEG")
         bitrate = 10080000LL; // use DVD max bit rate
-    else if (genOpt.cardtype == "HDTV")
+    else if (genOpt.cardtype == "DBOX2")
+        bitrate = 10080000LL; // use DVD max bit rate
+    else if (!CardUtil::IsEncoder(genOpt.cardtype))
         bitrate = 19400000LL; // 1080i
-    else if (genOpt.cardtype == "FIREWIRE")
-        bitrate = 19400000LL; // 1080i
-    else if (genOpt.cardtype == "DVB")
-        bitrate = 19400000LL; // 1080i
     else // frame grabber
         bitrate = 10080000LL; // use DVD max bit rate, probably too big
 
@@ -3392,19 +3400,38 @@
  */
 void TVRec::TuningFrequency(const TuningRequest &request)
 {
-    if (request.minorChan)
+    DTVChannel *dtvchan = GetDTVChannel();
+    if (dtvchan)
     {
-        MPEGStreamData *mpeg = GetDTVRecorder()->GetStreamData();
-        ATSCStreamData *atsc = dynamic_cast<ATSCStreamData*>(mpeg);
-        channel->SetChannelByString(request.channel);
-        atsc->SetDesiredChannel(request.majorChan, request.minorChan);
+        MPEGStreamData *mpeg = NULL;
+
+        if (GetDTVRecorder())
+            mpeg = GetDTVRecorder()->GetStreamData();
+
+        const QString tuningmode = (HasFlags(kFlagEITScannerRunning)) ?
+            dtvchan->GetSIStandard() :
+            dtvchan->GetSuggestedTuningMode(
+                kState_WatchingLiveTV == internalState);
+
+        dtvchan->SetTuningMode(tuningmode);
+
+        if (request.minorChan && (tuningmode == "atsc"))
+        {
+            channel->SetChannelByString(request.channel);
+
+            ATSCStreamData *atsc = dynamic_cast<ATSCStreamData*>(mpeg);
+            if (atsc)
+                atsc->SetDesiredChannel(request.majorChan, request.minorChan);
+        }
+        else if (request.progNum >= 0)
+        {
+            channel->SetChannelByString(request.channel);
+
+            if (mpeg)
+                mpeg->SetDesiredProgram(request.progNum);
+        }
     }
-    else if (request.progNum >= 0)
-    {
-        MPEGStreamData *mpeg = GetDTVRecorder()->GetStreamData();
-        channel->SetChannelByString(request.channel);
-        mpeg->SetDesiredProgram(request.progNum);
-    }
+
     if (request.IsOnSameMultiplex())
     {
         QStringList slist;
Index: libs/libmythtv/recordingprofile.cpp
===================================================================
--- libs/libmythtv/recordingprofile.cpp	(revision 12562)
+++ libs/libmythtv/recordingprofile.cpp	(working copy)
@@ -1037,7 +1037,7 @@
                     this,        SLOT(FiltersChanged(const QString&)));
         }
     }
-    else if (type.upper() == "DVB")
+    else
     {
         addChild(new RecordingType(*this));
     }
Index: libs/libmythtv/channel.cpp
===================================================================
--- libs/libmythtv/channel.cpp	(revision 12562)
+++ libs/libmythtv/channel.cpp	(working copy)
@@ -441,7 +441,7 @@
     if (!inputName.isEmpty())
         return ChannelBase::SwitchToInput(inputName, channum);
 
-    SetCachedATSCInfo("");
+    ClearDTVInfo();
 
     InputMap::const_iterator it = inputs.find(currentInputID);
     if (it == inputs.end())
@@ -516,13 +516,10 @@
     InitPictureAttributes();
 
     // 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));
+    SetDTVInfo(atsc_major, atsc_minor, netid, tsid, mpeg_prog_num);
 
     // Set this as the future start channel for this source
-    inputs[currentInputID]->startChanNum = curchannelname;
+    inputs[currentInputID]->startChanNum = QDeepCopy<QString>(curchannelname);
 
     return true;
 }
Index: libs/libmythtv/hdhrchannel.h
===================================================================
--- libs/libmythtv/hdhrchannel.h	(revision 12562)
+++ libs/libmythtv/hdhrchannel.h	(working copy)
@@ -29,6 +29,7 @@
 
     bool Open(void);
     void Close(void);
+    bool EnterPowerSavingMode(void);
 
     // Sets
     bool SetChannelByString(const QString &chan);
@@ -62,17 +63,20 @@
     bool DeviceSetTarget(unsigned short localPort);
     bool DeviceClearTarget(void);
 
-    QString DeviceGet(const QString &name);
-    QString DeviceSet(const QString &name, const QString &value);
+    QString DeviceGet(const QString &name, bool report_error_return = true);
+    QString DeviceSet(const QString &name, const QString &value,
+                      bool report_error_return = true);
 
-    QString TunerGet(const QString &name);
-    QString TunerSet(const QString &name, const QString &value);
+    QString TunerGet(const QString &name, bool report_error_return = true);
+    QString TunerSet(const QString &name, const QString &value,
+                     bool report_error_return = true);
 
   private:
     hdhr_socket_t  *_control_socket;
     uint            _device_id;
     uint            _device_ip;
     uint            _tuner;
+    bool            _ignore_filters;
     vector<uint>    _pids;
     mutable QMutex  _lock;
 };
Index: libs/libmythtv/dtvchannel.cpp
===================================================================
--- libs/libmythtv/dtvchannel.cpp	(revision 12562)
+++ libs/libmythtv/dtvchannel.cpp	(working copy)
@@ -8,6 +8,7 @@
 // MythTV headers
 #include "mythcontext.h"
 #include "mythdbcon.h"
+#include "cardutil.h"
 
 #define LOC QString("DTVChan(%1): ").arg(GetDevice())
 #define LOC_WARN QString("DTVChan(%1) Warning: ").arg(GetDevice())
@@ -15,7 +16,8 @@
 
 DTVChannel::DTVChannel(TVRec *parent)
     : ChannelBase(parent),
-      sistandard("mpeg"),         currentProgramNum(-1),
+      sistandard("mpeg"),         tuningMode(QString::null),
+      currentProgramNum(-1),
       currentATSCMajorChannel(0), currentATSCMinorChannel(0),
       currentTransportID(0),      currentOriginalNetworkID(0)
 {
@@ -87,56 +89,16 @@
     }
 }
 
-void DTVChannel::SetCachedATSCInfo(const QString &chan)
+void DTVChannel::SetDTVInfo(uint atsc_major, uint atsc_minor,
+                            uint dvb_orig_netid,
+                            uint mpeg_tsid, int mpeg_pnum)
 {
-    int progsep = chan.find("-");
-    int chansep = chan.find("_");
-
-    currentProgramNum        = -1;
-    currentOriginalNetworkID = 0;
-    currentTransportID       = 0;
-    currentATSCMajorChannel  = 0;
-    currentATSCMinorChannel  = 0;
-
-    if (progsep >= 0)
-    {
-        currentProgramNum = chan.right(chan.length() - progsep - 1).toInt();
-        currentATSCMajorChannel = chan.left(progsep).toInt();
-    }
-    else if (chansep >= 0)
-    {
-        currentATSCMinorChannel =
-            chan.right(chan.length() - chansep - 1).toInt();
-        currentATSCMajorChannel = chan.left(chansep).toInt();
-    }
-    else
-    {
-        bool ok;
-        int chanNum = chan.toInt(&ok);
-        if (ok && chanNum >= 10)
-        {
-            currentATSCMinorChannel = chanNum % 10;
-            currentATSCMajorChannel = chanNum / 10;
-        }
-    }
-
-    if (currentATSCMinorChannel > 0)
-    {
-        VERBOSE(VB_CHANNEL, LOC +
-                QString("SetCachedATSCInfo(%2): %3_%4").arg(chan)
-                .arg(currentATSCMajorChannel).arg(currentATSCMinorChannel));
-    }
-    else if ((0 == currentATSCMajorChannel) && (0 == currentProgramNum))
-    {
-        VERBOSE(VB_CHANNEL, LOC +
-                QString("SetCachedATSCInfo(%2): RESET").arg(chan));
-    }
-    else
-    {
-        VERBOSE(VB_CHANNEL, LOC +
-                QString("SetCachedATSCInfo(%2): %3-%4").arg(chan)
-                .arg(currentATSCMajorChannel).arg(currentProgramNum));
-    }
+    QMutexLocker locker(&dtvinfo_lock);
+    currentProgramNum        = mpeg_pnum;
+    currentATSCMajorChannel  = atsc_major;
+    currentATSCMinorChannel  = atsc_minor;
+    currentTransportID       = mpeg_tsid;
+    currentOriginalNetworkID = dvb_orig_netid;
 }
 
 QString DTVChannel::GetSIStandard(void) const
@@ -148,5 +110,35 @@
 void DTVChannel::SetSIStandard(const QString &si_std)
 {
     QMutexLocker locker(&dtvinfo_lock);
-    sistandard = QDeepCopy<QString>(si_std);
+    sistandard = QDeepCopy<QString>(si_std.lower());
 }
+
+QString DTVChannel::GetSuggestedTuningMode(bool is_live_tv) const
+{
+    uint cardid = GetCardID();
+    QString input = GetCurrentInput();
+
+    uint quickTuning = 0;
+    if (cardid && !input.isEmpty())
+        quickTuning = CardUtil::GetQuickTuning(cardid, input);
+
+    bool useQuickTuning = (quickTuning && is_live_tv) || (quickTuning > 1);
+
+    QMutexLocker locker(&dtvinfo_lock);
+    if (!useQuickTuning && ((sistandard == "atsc") || (sistandard == "dvb")))
+        return QDeepCopy<QString>(sistandard);
+
+    return "mpeg";
+}
+
+QString DTVChannel::GetTuningMode(void) const
+{
+    QMutexLocker locker(&dtvinfo_lock);
+    return QDeepCopy<QString>(tuningMode);
+}
+
+void DTVChannel::SetTuningMode(const QString &tuning_mode)
+{
+    QMutexLocker locker(&dtvinfo_lock);
+    tuningMode = QDeepCopy<QString>(tuning_mode.lower());
+}
