Index: tv_play.h
===================================================================
--- tv_play.h	(revision 24265)
+++ tv_play.h	(working copy)
@@ -402,7 +402,7 @@
     QString GetQueuedChanNum(void) const;
     uint    GetQueuedChanID(void)  const { return queuedChanID; }
 
-    void SwitchSource(uint source_direction);
+    void SwitchSource(PlayerContext*, uint source_direction);
     void SwitchInputs(PlayerContext*, uint inputid);
     void ToggleInputs(PlayerContext*, uint inputid = 0);
     void SwitchCards(PlayerContext*,
Index: hdhrstreamhandler.cpp
===================================================================
--- hdhrstreamhandler.cpp	(revision 24265)
+++ hdhrstreamhandler.cpp	(working copy)
@@ -483,6 +483,15 @@
 
 bool HDHRStreamHandler::UpdateFilters(void)
 {
+    if (_tune_mode == hdhrTuneModeFrequency)
+        _tune_mode = hdhrTuneModeFrequencyPid;
+
+    if (_tune_mode != hdhrTuneModeFrequencyPid)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "UpdateFilters called in wrong tune mode");
+        return false;
+    }
+
 #ifdef DEBUG_PID_FILTERS
     VERBOSE(VB_RECORD, LOC + "UpdateFilters()");
 #endif // DEBUG_PID_FILTERS
@@ -493,10 +502,6 @@
     vector<uint> range_min;
     vector<uint> range_max;
 
-// FIXME
-//    if (_ignore_filters)
- //       return true;
-
     for (uint i = 0; i < _pid_info.size(); i++)
     {
         uint pid_min = _pid_info[i];
@@ -731,8 +736,9 @@
 
 bool HDHRStreamHandler::TuneChannel(const QString &chn)
 {
+    _tune_mode = hdhrTuneModeFrequency;
+
     QString current = TunerGet("channel");
-
     if (current == chn)
     {
         VERBOSE(VB_RECORD, QString(LOC + "Not Re-Tuning channel %1").arg(chn));
@@ -746,7 +752,25 @@
 
 bool HDHRStreamHandler::TuneProgram(uint mpeg_prog_num)
 {
+    if (_tune_mode == hdhrTuneModeFrequency)
+        _tune_mode = hdhrTuneModeFrequencyProgram;
+
+    if (_tune_mode != hdhrTuneModeFrequencyProgram)
+    {
+        VERBOSE(VB_IMPORTANT, LOC_ERR + "TuneProgram called in wrong tune mode");
+        return false;
+    }
+
     VERBOSE(VB_RECORD, QString(LOC + "Tuning program %1").arg(mpeg_prog_num));
     return !TunerSet(
         "program", QString::number(mpeg_prog_num), false).isEmpty();
 }
+
+bool HDHRStreamHandler::TuneVChannel(const QString &vchn)
+{
+    _tune_mode = hdhrTuneModeVChannel;
+
+    VERBOSE(VB_RECORD, QString(LOC + "Tuning vchannel %1").arg(vchn));
+    return !TunerSet(
+        "vchannel", vchn).isEmpty();
+}
Index: hdhrchannel.cpp
===================================================================
--- hdhrchannel.cpp	(revision 24265)
+++ hdhrchannel.cpp	(working copy)
@@ -182,10 +182,14 @@
         }
         else
         {
-            VERBOSE(VB_IMPORTANT, LOC_ERR +
-                    "dtv_multiplex data is required for tuning");
+            if (!_stream_handler->TuneVChannel(channum))
+            {
+                VERBOSE(VB_IMPORTANT, LOC_ERR +
+                        "dtv_multiplex data is required for tuning");
+                return false;
+            }
 
-            return false;
+            SetSIStandard(si_std);
         }
     }
     else if (!ChangeExternalChannel(freqid))
@@ -202,10 +206,6 @@
     QString tmpX = m_curchannelname; tmpX.detach();
     m_inputs[m_currentInputID]->startChanNum = tmpX;
 
-    // Turn on the program filtering if tuning to MPEG stream
-    if (mpeg_prog_num && (GetTuningMode() == "mpeg"))
-        _stream_handler->TuneProgram(mpeg_prog_num);
-
     return true;
 }
 
Index: tv_play.cpp
===================================================================
--- tv_play.cpp	(revision 24265)
+++ tv_play.cpp	(working copy)
@@ -4615,9 +4615,9 @@
     else if (has_action("NEXTFAV", actions) && islivetv)
         ChangeChannel(ctx, CHANNEL_DIRECTION_FAVORITE);
     else if (has_action("NEXTSOURCE", actions) && islivetv)
-        SwitchSource(kNextSource);
+        SwitchSource(ctx, kNextSource);
     else if (has_action("PREVSOURCE", actions) && islivetv)
-        SwitchSource(kPreviousSource);
+        SwitchSource(ctx, kPreviousSource);
     else if (has_action("NEXTINPUT", actions) && islivetv)
         ToggleInputs(ctx);
     else if (has_action("NEXTCARD", actions) && islivetv)
@@ -6313,17 +6313,11 @@
         SetMuteTimer(ctx, kMuteTimeout);
 }
 
-void TV::SwitchSource(uint source_direction)
+void TV::SwitchSource(PlayerContext *ctx, uint source_direction)
 {
-    PlayerContext *actx = GetPlayerReadLock(-1, __FILE__, __LINE__);
-    if (!actx->recorder)
-    {
-        ReturnPlayerLock(actx);
-        return;
-    }
     QMap<uint,InputInfo> sources;
     vector<uint> cardids = RemoteRequestFreeRecorderList();
-    uint         cardid  = actx->GetCardID();
+    uint         cardid  = ctx->GetCardID();
     cardids.push_back(cardid);
     stable_sort(cardids.begin(), cardids.end());
 
@@ -6331,7 +6325,7 @@
     excluded_cardids.push_back(cardid);
 
     InfoMap info;
-    actx->recorder->GetChannelInfo(info);
+    ctx->recorder->GetChannelInfo(info);
     uint sourceid = info["sourceid"].toUInt();
 
     vector<uint>::const_iterator it = cardids.begin();
@@ -6361,7 +6355,6 @@
 
     if (sit == sources.end())
     {
-        ReturnPlayerLock(actx);
         return;
     }
 
@@ -6389,12 +6382,10 @@
 
     if (sit == beg)
     {
-        ReturnPlayerLock(actx);
         return;
     }
 
     switchToInputId = (*sit).inputid;
-    ReturnPlayerLock(actx);
 
     QMutexLocker locker(&timerIdLock);
     if (!switchToInputTimerId)
Index: hdhrstreamhandler.h
===================================================================
--- hdhrstreamhandler.h	(revision 24265)
+++ hdhrstreamhandler.h	(working copy)
@@ -27,6 +27,14 @@
 struct hdhomerun_device_t { int dummy; };
 #endif
 
+enum HDHRTuneMode {
+    hdhrTuneModeNone = 0,
+    hdhrTuneModeFrequency,
+    hdhrTuneModeFrequencyPid,
+    hdhrTuneModeFrequencyProgram,
+    hdhrTuneModeVChannel
+};
+
 typedef QMap<uint,int> FilterMap;
 
 //#define RETUNE_TIMEOUT 5000
@@ -50,6 +58,7 @@
     // Commands
     bool TuneChannel(const QString &chanid);
     bool TuneProgram(uint mpeg_prog_num);
+    bool TuneVChannel(const QString &vchn);
     bool EnterPowerSavingMode(void);
 
 
@@ -91,9 +100,10 @@
 
   private:
     hdhomerun_device_t *_hdhomerun_device;
-    uint                _tuner;
-    QString             _devicename;
+    uint                 _tuner;
+    QString              _devicename;
     vector<DTVTunerType> _tuner_types;
+    HDHRTuneMode         _tune_mode; // debug self check
 
     mutable QMutex    _start_stop_lock;
     bool              _running;
