Index: libs/libmythtv/recordingprofile.h
===================================================================
--- libs/libmythtv/recordingprofile.h	(revision 8741)
+++ libs/libmythtv/recordingprofile.h	(working copy)
@@ -75,6 +75,7 @@
     RecordingProfile(QString profName = NULL);
     virtual void loadByID(int id);
     virtual bool loadByCard(QString name, int cardid);
+    virtual bool loadByType(QString name, QString cardtype);
     virtual bool loadByGroup(QString name, QString group);
     virtual int exec();
 
Index: libs/libmythtv/NuppelVideoPlayer.cpp
===================================================================
--- libs/libmythtv/NuppelVideoPlayer.cpp	(revision 8741)
+++ libs/libmythtv/NuppelVideoPlayer.cpp	(working copy)
@@ -2443,6 +2443,7 @@
 
         if ((!paused || eof) && livetvchain)
         {
+            cerr<<".";
             if (livetvchain->NeedsToSwitch())
                 SwitchToProgram();
             else if (livetvchain->NeedsToJump())
Index: libs/libmythtv/tv_play.cpp
===================================================================
--- libs/libmythtv/tv_play.cpp	(revision 8741)
+++ libs/libmythtv/tv_play.cpp	(working copy)
@@ -28,7 +28,7 @@
 #include "jobqueue.h"
 #include "audiooutput.h"
 #include "DisplayRes.h"
-#include "signalmonitor.h"
+#include "signalmonitorvalue.h"
 #include "scheduledrecording.h"
 #include "config.h"
 #include "livetvchain.h"
@@ -1033,27 +1033,6 @@
     stateLock.unlock();
 }
 
-uint TV::GetLockTimeout(uint cardid)
-{
-    uint timeout = 0xffffffff;
-    MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT channel_timeout, cardtype "
-                  "FROM capturecard "
-                  "WHERE cardid = :CARDID");
-    query.bindValue(":CARDID", cardid);
-    if (!query.exec() || !query.isActive())
-        MythContext::DBError("Getting timeout", query);
-    else if (query.next() &&
-             SignalMonitor::IsSupported(query.value(1).toString()))
-        timeout = max(query.value(0).toInt(), 500);
-
-    VERBOSE(VB_PLAYBACK, LOC + QString("GetLockTimeout(%1): "
-                                       "Set lock timeout to %2 ms")
-            .arg(cardid).arg(timeout));
-
-    return timeout;
-}
-
 /** \fn TV::StartRecorder(RemoteEncoder*, int)
  *  \brief Starts recorder, must be called before StartPlayer().
  *  \param maxWait How long to wait for RecorderBase to start recording.
@@ -1077,10 +1056,6 @@
     VERBOSE(VB_PLAYBACK, LOC + "StartRecorder(): took "<<t.elapsed()
             <<" ms to start recorder.");
 
-    // Get timeout for this recorder
-    lockTimeout[rec->GetRecorderNumber()] =
-        GetLockTimeout(rec->GetRecorderNumber());
-
     // Cache starting frame rate for this recorder
     if (rec == recorder)
         frameRate = recorder->GetFrameRate();
@@ -3465,12 +3440,13 @@
 
     // Pause the backend recorder, send command, and then unpause..
     PauseLiveTV();
-    activerecorder->ToggleInputs();
+    lockTimerOn = false;
+    QString inputname = activerecorder->SetInput("SwitchToNextInput");
     UnpauseLiveTV();
 
     // If activenvp is main nvp, show new input in on screen display
     if (nvp && activenvp == nvp)
-        UpdateOSDInput();
+        UpdateOSDInput(inputname);
 }
 
 void TV::ToggleChannelFavorite(void)
@@ -4025,35 +4001,35 @@
     update_osd_pos = true;
 }
 
-void TV::UpdateOSDInput(void)
+void TV::UpdateOSDInput(QString inputname)
 {
+    QString displayName = QString::null;
+
     if (!activerecorder || !tvchain)
         return;
 
-    QString name = tvchain->GetInputName(-1);
-    QString displayName = "";
-    QString msg;
+    int cardid = activerecorder->GetRecorderNumber();
 
+    if (inputname.isEmpty())
+        inputname = tvchain->GetInputName(-1);
+
+    // Try to get display name
     MSqlQuery query(MSqlQuery::InitCon());
-    query.prepare("SELECT displayname FROM cardinput "
-                  "WHERE cardid = :CARDID AND inputname = :INPUTNAME");
-    query.bindValue(":CARDID", activerecorder->GetRecorderNumber());
-    query.bindValue(":INPUTNAME", name);
-    query.exec();
-    if (query.isActive() && query.size() > 0)
-    {
-        query.next();
+    query.prepare("SELECT displayname "
+                  "FROM cardinput "
+                  "WHERE inputname = :INPUTNAME AND "
+                  "      cardid    = :CARDID");
+    query.bindValue(":CARDID",    cardid);
+    query.bindValue(":INPUTNAME", inputname);
+    if (query.exec() && query.isActive() && query.size() && query.next())
         displayName = query.value(0).toString();
-    }
 
-    if ( displayName == "")
-        msg = QString("%1: %2")
-                .arg(activerecorder->GetRecorderNumber()).arg(name);
-    else
-        msg = displayName;
+    // If a display name doesn't exist use cardid and inputname
+    if (displayName.isEmpty())
+        displayName = QString("%1: %2").arg(cardid).arg(inputname);
 
     if (GetOSD())
-        GetOSD()->SetSettingsText(msg, 3);
+        GetOSD()->SetSettingsText(displayName, 3);
 }
 
 /** \fn TV::UpdateOSDSignal(const QStringList&)
@@ -4179,7 +4155,8 @@
     bool timed_out = false;
     if (activerecorder)
     {
-        uint timeout = lockTimeout[activerecorder->GetRecorderNumber()];
+        QString input = activerecorder->GetInput();
+        uint timeout  = activerecorder->GetSignalLockTimeout(input);
         timed_out = lockTimerOn && ((uint)lockTimer.elapsed() > timeout);
     }
     OSD *osd = GetOSD();
@@ -6019,7 +5996,9 @@
     osdlock.unlock();
 
     lockTimerOn = false;
-    uint timeout = lockTimeout[activerecorder->GetRecorderNumber()];
+
+    QString input = activerecorder->GetInput();
+    uint timeout = activerecorder->GetSignalLockTimeout(input);
     if (timeout < 0xffffffff)
     {
         lockTimer.start();
Index: libs/libmythtv/remoteencoder.h
===================================================================
--- libs/libmythtv/remoteencoder.h	(revision 8741)
+++ libs/libmythtv/remoteencoder.h	(working copy)
@@ -39,7 +39,9 @@
     void CancelNextRecording(bool cancel);
 
     void SetLiveRecording(bool recording);
-    void ToggleInputs(void);
+    QStringList GetInputs(void);
+    QString GetInput(void);
+    QString SetInput(QString);
     int ChangeContrast(bool direction);
     int ChangeBrightness(bool direction);
     int ChangeColour(bool direction);
@@ -48,7 +50,8 @@
     void ChangeDeinterlacer(int deint_mode);
     void ToggleChannelFavorite(void);
     void SetChannel(QString channel);
-    int SetSignalMonitoringRate(int msec, bool notifyFrontend = true);
+    int  SetSignalMonitoringRate(int msec, bool notifyFrontend = true);
+    uint GetSignalLockTimeout(QString input);
     bool CheckChannel(QString channel);
     bool ShouldSwitchToAnotherCard(QString channelid);
     bool CheckChannelPrefix(const QString&,uint&,bool&,QString&);
Index: libs/libmythtv/dvbchannel.cpp
===================================================================
--- libs/libmythtv/dvbchannel.cpp	(revision 8741)
+++ libs/libmythtv/dvbchannel.cpp	(working copy)
@@ -176,7 +176,7 @@
                 .arg(it.key()).arg(*it)
                 .arg(inputChannel[it.key()]));
     }
-    currentcapchannel = nextcapchannel = GetNextInput();
+    currentcapchannel = nextcapchannel = GetNextInputNum();
     VERBOSE(VB_CHANNEL, LOC + QString("Current Input #%1: '%2'")
             .arg(GetCurrentInputNum()).arg(GetCurrentInput()));
 }
@@ -326,8 +326,8 @@
 bool DVBChannel::SwitchToInput(int newcapchannel, bool setstarting)
 {
     (void)setstarting;
-    if(inputChannel[newcapchannel] != "")
-     {
+    if (!inputChannel[newcapchannel].isEmpty())
+    {
         nextcapchannel = newcapchannel;
         return SetChannelByString(inputChannel[newcapchannel]);
     }
Index: libs/libmythtv/tv_play.h
===================================================================
--- libs/libmythtv/tv_play.h	(revision 8741)
+++ libs/libmythtv/tv_play.h	(working copy)
@@ -186,7 +186,6 @@
     bool RequestNextRecorder(bool showDialogs);
     void DeleteRecorder();
 
-    static uint GetLockTimeout(uint cardid);
     bool StartRecorder(RemoteEncoder *rec, int maxWait=-1);
     bool StartPlayer(bool isWatchingRecording, int maxWait=-1);
     void StartOSD(void);
@@ -269,7 +268,7 @@
     void ToggleOSD(bool includeStatusOSD); 
     void UpdateOSDProgInfo(const char *whichInfo);
     void UpdateOSDSeekMessage(const QString &mesg, int disptime);
-    void UpdateOSDInput(void);
+    void UpdateOSDInput(QString inputname = QString::null);
     void UpdateOSDTextEntry(const QString &message);
     void UpdateOSDSignal(const QStringList& strlist);
     void UpdateOSDTimeoutMessage(void);
@@ -434,7 +433,6 @@
     // Channel changing timeout notification variables
     QTime   lockTimer;
     bool    lockTimerOn;
-    QMap<uint,uint> lockTimeout;
 
     // Previous channel functionality state variables
     str_vec_t prevChan;       ///< Previous channels
Index: libs/libmythtv/remoteencoder.cpp
===================================================================
--- libs/libmythtv/remoteencoder.cpp	(revision 8741)
+++ libs/libmythtv/remoteencoder.cpp	(working copy)
@@ -8,6 +8,7 @@
 #include "programinfo.h"
 #include "util.h"
 #include "mythcontext.h"
+#include "signalmonitor.h"
 
 RemoteEncoder::RemoteEncoder(int num, const QString &host, short port)
     : recordernum(num),       controlSock(NULL),      remotehost(host),
@@ -313,14 +314,37 @@
     SendReceiveStringList(strlist);
 }
 
-void RemoteEncoder::ToggleInputs(void)
+QStringList RemoteEncoder::GetInputs(void)
 {
     QStringList strlist = QString("QUERY_RECORDER %1").arg(recordernum);
-    strlist << "TOGGLE_INPUTS";
+    strlist << "GET_INPUTS";
 
     SendReceiveStringList(strlist);
 
+    return strlist;
+}
+
+QString RemoteEncoder::GetInput(void)
+{
+    QStringList strlist = QString("QUERY_RECORDER %1").arg(recordernum);
+    strlist << "GET_INPUT";
+
+    SendReceiveStringList(strlist);
+
+    return strlist[0]; 
+}
+
+QString RemoteEncoder::SetInput(QString input)
+{
+    QStringList strlist = QString("QUERY_RECORDER %1").arg(recordernum);
+    strlist << "SET_INPUT";
+    strlist << input;
+
+    SendReceiveStringList(strlist);
+
     lastchannel = "";
+
+    return strlist[0];
 }
 
 void RemoteEncoder::ToggleChannelFavorite(void)
@@ -382,6 +406,28 @@
     return retval;
 }
 
+uint RemoteEncoder::GetSignalLockTimeout(QString input)
+{
+    uint cardid  = recordernum;
+    uint timeout = 0xffffffff;
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare("SELECT channel_timeout, cardtype "
+                  "FROM capturecard "
+                  "WHERE cardid = :CARDID");
+    query.bindValue(":CARDID", cardid);
+    if (!query.exec() || !query.isActive())
+        MythContext::DBError("Getting timeout", query);
+    else if (query.next() &&
+             SignalMonitor::IsSupported(query.value(1).toString()))
+        timeout = max(query.value(0).toInt(), 500);
+
+    VERBOSE(VB_PLAYBACK, "RemoteEncoder: " +
+            QString("GetSignalLockTimeout(%1): Set lock timeout to %2 ms")
+            .arg(cardid).arg(timeout));
+
+    return timeout;
+}
+
 /** \fn RemoteEncoder::ChangeContrast(bool)
  *  \brief Changes contrast of a recording.
  *
Index: libs/libmythtv/dbcheck.cpp
===================================================================
--- libs/libmythtv/dbcheck.cpp	(revision 8741)
+++ libs/libmythtv/dbcheck.cpp	(working copy)
@@ -1990,6 +1990,17 @@
             return false;
     }
 
+    if (dbver == "1122")
+    {
+        const QString updates[] = {
+"ALTER TABLE cardinput ADD COLUMN inputtype VARCHAR(20) NOT NULL DEFAULT '';",
+"ALTER TABLE cardinput ADD COLUMN inputdev VARCHAR(128) NOT NULL DEFAULT '';",
+""
+};
+        if (!performActualUpdate(updates, "1123", dbver))
+            return false;
+    }
+
 // Drop xvmc_buffer_settings table in 0.20
 // Drop dvb_dmx_buf_size and dvb_pkt_buf_size columns of channel in 0.20
 
Index: libs/libmythtv/livetvchain.cpp
===================================================================
--- libs/libmythtv/livetvchain.cpp	(revision 8741)
+++ libs/libmythtv/livetvchain.cpp	(working copy)
@@ -460,7 +460,7 @@
  */
 void LiveTVChain::SwitchToNext(bool up)
 {
-    //VERBOSE(VB_PLAYBACK, LOC + "SwitchToNext("<<(up?"up":"down")<<")");
+    VERBOSE(VB_PLAYBACK, LOC + "SwitchToNext("<<(up?"up":"down")<<")");
     if (up && HasNext())
         SwitchTo(m_curpos + 1);
     else if (!up && HasPrev())
@@ -475,6 +475,8 @@
 
 void LiveTVChain::JumpToNext(bool up, int pos)
 {
+    VERBOSE(VB_PLAYBACK, LOC + "JumpToNext("<<(up?"up":"down")
+            <<", "<<pos<<")");
     m_jumppos = pos;
     SwitchToNext(up);
 }
Index: libs/libmythtv/tv_rec.cpp
===================================================================
--- libs/libmythtv/tv_rec.cpp	(revision 8741)
+++ libs/libmythtv/tv_rec.cpp	(working copy)
@@ -132,27 +132,15 @@
 {
 }
 
-/** \fn TVRec::Init()
- *  \brief Performs instance initialization, returns true on success.
- *
- *  \return Returns true on success, false on failure.
- */
-bool TVRec::Init(void)
+bool TVRec::CreateChannel(void)
 {
-    QMutexLocker lock(&stateChangeLock);
-
-    bool ok = GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt);
-
-    if (!ok)
-        return false;
-
     QString startchannel = GetStartChannel(cardid, genOpt.defaultinput);
-
     bool init_run = false;
     if (genOpt.cardtype == "DVB")
     {
 #ifdef USING_DVB_EIT
-        scanner = new EITScanner();
+        if (!scanner)
+            scanner = new EITScanner();
 #endif // USING_DVB_EIT
 
 #ifdef USING_DVB
@@ -203,21 +191,39 @@
             rbFileExt = "nuv";
     }
 
-    if (!init_run)
-    {
-        QString msg = QString(
-            "%1 card configured on video device %2, \n"
-            "but MythTV was not compiled with %2 support. \n"
-            "\n"
-            "Recompile MythTV with %3 support or remove the card \n"
-            "from the configuration and restart MythTV.")
-            .arg(genOpt.cardtype).arg(genOpt.videodev)
-            .arg(genOpt.cardtype).arg(genOpt.cardtype);
-        VERBOSE(VB_IMPORTANT, LOC_ERR + msg);
-        SetFlags(kFlagErrored);
+    if (init_run)
+        return true;
+
+    QString msg = QString(
+        "%1 card configured on video device %2, \n"
+        "but MythTV was not compiled with %2 support. \n"
+        "\n"
+        "Recompile MythTV with %3 support or remove the card \n"
+        "from the configuration and restart MythTV.")
+        .arg(genOpt.cardtype).arg(genOpt.videodev)
+        .arg(genOpt.cardtype).arg(genOpt.cardtype);
+
+    VERBOSE(VB_IMPORTANT, LOC_ERR + msg);
+
+    SetFlags(kFlagErrored);
+
+    return false;
+}
+
+/** \fn TVRec::Init(void)
+ *  \brief Performs instance initialization, returns true on success.
+ *
+ *  \return Returns true on success, false on failure.
+ */
+bool TVRec::Init(void)
+{
+    QMutexLocker lock(&stateChangeLock);
+
+    if (!GetDevices(cardid, genOpt, dvbOpt, fwOpt, dboxOpt) || !CreateChannel())
         return false;
-    }
 
+    origGenOpt = genOpt;
+
     transcodeFirst    =
         gContext->GetNumSetting("AutoTranscodeBeforeAutoCommflag", 0);
     earlyCommFlag     = gContext->GetNumSetting("AutoCommflagWhileRecording", 0);
@@ -1650,9 +1656,6 @@
 
     if (SignalMonitor::IsSupported(genOpt.cardtype) && channel->Open())
     {
-        // TODO reset the tuner hardware
-        //channel->SwitchToInput(channel->GetCurrentInputNum(), true);
-
         signalMonitor = SignalMonitor::Init(genOpt.cardtype, cardid, channel);
     }
     
@@ -2979,6 +2982,84 @@
     return ret;
 }
 
+/** \fn TVRec::GetConnectedInputs(void) const
+ *  \brief Returns TVRec's recorders connected inputs.
+ */
+QStringList TVRec::GetConnectedInputs(void) const
+{
+    QStringList list;
+    if (channel)
+        list = channel->GetConnectedInputs();
+    return list;
+}
+
+/** \fn TVRec::GetInput(void) const
+ *  \brief Returns current input.
+ */
+QString TVRec::GetInput(void) const
+{
+    if (channel)
+        return channel->GetCurrentInput();
+    return QString::null;
+}
+
+/** \fn TVRec::SetInput(QString)
+ *  \brief Changes to the specified input.
+ *
+ *   You must call PauseRecorder(void) before calling this.
+ *
+ *  \param input Input to switch to, or "SwitchToNectInput".
+ *  \return input we have switched to
+ */
+QString TVRec::SetInput(QString input, uint requestType)
+{
+    QMutexLocker lock(&stateChangeLock);
+    QString origIn = input;
+    VERBOSE(VB_RECORD, LOC + "SetInput("<<input<<") -- begin");
+
+    if (!channel)
+    {
+        VERBOSE(VB_RECORD, LOC + "SetInput() -- end  no channel class");
+        return QString::null;
+    }
+
+    input = (input == "SwitchToNextInput") ? channel->GetNextInput() : input;
+
+    if (input == channel->GetCurrentInput())
+    {
+        VERBOSE(VB_RECORD, LOC + "SetInput("<<origIn<<":"<<input
+                <<") -- end  nothing to do");
+        return input;
+    }
+
+    QString name = channel->GetNextInputStartChan();
+    
+    // Detect tuning request type if needed
+    if (requestType & kFlagDetect)
+    {
+        WaitForEventThreadSleep();
+        requestType = lastTuningRequest.flags & (kFlagRec | kFlagNoRec);
+    }
+
+    // Clear the RingBuffer reset flag, in case we wait for a reset below
+    ClearFlags(kFlagRingBufferReady);
+
+    // Actually add the tuning request to the queue, and
+    // then wait for it to start tuning
+    tuningRequests.enqueue(TuningRequest(requestType, name, input));
+    WaitForEventThreadSleep();
+
+    // If we are using a recorder, wait for a RingBuffer reset
+    if (requestType & kFlagRec)
+    {
+        while (!HasFlags(kFlagRingBufferReady))
+            WaitForEventThreadSleep();
+    }
+    VERBOSE(VB_RECORD, LOC + "SetInput("<<origIn<<":"<<input<<") -- end");
+
+    return GetInput();
+}
+
 /** \fn TVRec::SetChannel(QString,uint)
  *  \brief Changes to a named channel on the current tuner.
  *
@@ -3190,8 +3271,8 @@
 {
     if (tuningRequests.size())
     {
+        VERBOSE(VB_RECORD, LOC + "Request: " + tuningRequests[0].toString());
         const TuningRequest *request = &tuningRequests.front();
-        VERBOSE(VB_RECORD, LOC + "Request: "<<request->toString());
         TuningShutdowns(*request);
 
         // Now we start new stuff
@@ -3256,6 +3337,29 @@
  */
 void TVRec::TuningShutdowns(const TuningRequest &request)
 {
+    QString curType(""), curDev(""), newType(""), newDev("");
+    if (channel && !request.input.isEmpty())
+    {
+        QString current_input = channel->GetCurrentInput();
+        curType = channel->GetInputType(current_input, curDev);
+        curType = curType.isEmpty() ? origGenOpt.cardtype : curType;
+        curDev  = curDev.isEmpty()  ? origGenOpt.videodev : curDev;
+        
+        newType = channel->GetInputType(request.input, newDev);
+        newType = newType.isEmpty() ? origGenOpt.cardtype : newType;
+        newDev  = newDev.isEmpty()  ? origGenOpt.videodev : newDev;
+    }
+
+    VERBOSE(VB_IMPORTANT, LOC + "Tuner Type: <"<<curType<<":"<<newType<<">");
+    VERBOSE(VB_IMPORTANT, LOC + "Tuner Dev:  <"<<curDev <<":"<<newDev <<">");
+
+    bool force_teardown = false;
+    if (curType != newType)
+    {
+        // TODO handle total shutdown...
+        force_teardown = true;
+    }
+
 #ifdef USING_DVB_EIT
     if (!(request.flags & kFlagEITScan) && HasFlags(kFlagEITScannerRunning))
     {
@@ -3284,7 +3388,7 @@
 
     // At this point any waits are canceled.
 
-    if ((request.flags & kFlagNoRec))
+    if ((request.flags & kFlagNoRec) || force_teardown)
     {
         if (HasFlags(kFlagDummyRecorderRunning))
         {
@@ -3309,7 +3413,22 @@
         CloseChannel();
         // At this point the channel is shut down
     }
+    
+    if (force_teardown)
+    {
+        VERBOSE(VB_IMPORTANT, "Recreating channel...");
+        channel->Close();
+        delete channel;
+        channel = NULL;
+        genOpt.cardtype     = newType;
+        genOpt.videodev     = newDev;
+        genOpt.defaultinput = request.input;
+        CreateChannel();
 
+        if (!(request.flags & kFlagNoRec))
+            channel->Open();
+    }
+
     if (ringBuffer && (request.flags & kFlagKillRingBuffer))
     {
         VERBOSE(VB_RECORD, LOC + "Tearing down RingBuffer");
@@ -3371,8 +3490,6 @@
 
         if (!input.isEmpty())
             ok = channel->SwitchToInput(input, channum);
-        else if (channum.find("ToggleInputs") >= 0)
-            ok = channel->ToggleInputs();
         else
             ok = channel->SetChannelByString(channum);
     }
@@ -3543,27 +3660,6 @@
     return true;
 }
 
-static void load_recording_profile(
-    RecordingProfile &profile, ProgramInfo *rec, int cardid)
-{
-    QString profileName = "Live TV";
-    bool done = false;
-
-    if (rec)
-    {
-        profileName = rec->GetScheduledRecording()->getProfileName();
-        if (!profileName.isEmpty())
-            done = profile.loadByCard(profileName, cardid);
-        profileName = (done) ? profileName : QString("Default");
-    }
-
-    if (!done)
-        profile.loadByCard(profileName, cardid);
-
-    QString msg = QString("Using profile '%1' to record").arg(profileName);
-    VERBOSE(VB_RECORD, LOC + msg);
-}
-
 static int init_jobs(const ProgramInfo *rec, RecordingProfile &profile,
                       bool on_host, bool transcode_bfr_comm, bool on_line_comm)
 {
@@ -3622,9 +3718,20 @@
         had_dummyrec = true;
     }
 
+    ProgramInfo *rec = lastTuningRequest.program;    
+    QString profileName = (tvchain) ? QString("Live TV") :
+        rec->GetScheduledRecording()->getProfileName();
+
     RecordingProfile profile;
-    ProgramInfo *rec = lastTuningRequest.program;
-    load_recording_profile(profile, rec, cardid);
+    if (!profile.loadByType(profileName, genOpt.cardtype))
+    {
+        profileName = "Default";
+        profile.loadByType(profileName, genOpt.cardtype);
+    }
+
+    VERBOSE(VB_RECORD, LOC + QString("Using profile '%1' to record")
+            .arg(profileName));
+
     if (tvchain)
     {
         bool ok;
@@ -3634,7 +3741,7 @@
             SetFlags(kFlagRingBufferReady);
         }
         else
-            ok = SwitchLiveTVRingBuffer(true, !had_dummyrec);
+            ok = SwitchLiveTVRingBuffer(true, !had_dummyrec && recorder);
         if (!ok)
         {
             VERBOSE(VB_IMPORTANT, LOC_ERR + "Failed to create RingBuffer 2");
@@ -3725,7 +3832,7 @@
     if (GetV4LChannel())
         channel->SetFd(recorder->GetVideoFd());
 
-    SetFlags(kFlagRecorderRunning);
+    SetFlags(kFlagRecorderRunning | kFlagRingBufferReady);
 
     if (!tvchain)
         autoRunJobs = init_jobs(rec, profile, runJobOnHostOnly,
@@ -3911,7 +4018,7 @@
         }
     }
     if (kFlagRingBufferReady & f)
-        msg += "RingBufferReset,";
+        msg += "RingBufferReady,";
 
     if (msg.isEmpty())
         msg = QString("0x%1").arg(f,0,16);
Index: libs/libmythtv/recordingprofile.cpp
===================================================================
--- libs/libmythtv/recordingprofile.cpp	(revision 8741)
+++ libs/libmythtv/recordingprofile.cpp	(working copy)
@@ -905,6 +905,43 @@
     return false;
 }
 
+bool RecordingProfile::loadByType(QString name, QString cardtype) 
+{
+    QString hostname = gContext->GetHostName();
+    int recid = 0;
+
+    MSqlQuery result(MSqlQuery::InitCon());
+    result.prepare(
+        "SELECT recordingprofiles.id, profilegroups.hostname, "
+        "       profilegroups.is_default "
+        "FROM recordingprofiles, profilegroups, capturecard "
+        "WHERE profilegroups.id       = recordingprofiles.profilegroup AND "
+        "      profilegroups.cardtype = :CARDTYPE                      AND "
+        "      recordingprofiles.name = :NAME");
+    result.bindValue(":CARDTYPE", cardtype);
+    result.bindValue(":NAME", name);
+
+    if (result.exec() && result.isActive() && result.size() > 0)
+    {
+        while (result.next())
+        {
+            if (result.value(1).toString() == hostname)
+            {
+                recid = result.value(0).toInt();
+                break;
+            }
+            else if (result.value(2).toInt() == 1)
+                recid = result.value(0).toInt();
+        }
+    }
+    if (recid)
+    {
+        loadByID(recid);
+        return true;
+    }
+    return false;
+}
+
 bool RecordingProfile::loadByGroup(QString name, QString group) 
 {
     MSqlQuery result(MSqlQuery::InitCon());
Index: libs/libmythtv/channelbase.h
===================================================================
--- libs/libmythtv/channelbase.h	(revision 8741)
+++ libs/libmythtv/channelbase.h	(working copy)
@@ -38,9 +38,6 @@
     virtual bool Open(void) = 0;
     /// \brief Closes the channel changing hardware to use.
     virtual void Close(void) = 0;
-    /// \brief Switches to another input on hardware, 
-    ///        and sets the channel is setstarting is true.
-    virtual bool SwitchToInput(int newcapchannel, bool setstarting) = 0;
     virtual bool SetChannelByString(const QString &chan) = 0;
     /// \brief Reports whether channel is already open
     virtual bool IsOpen(void) const = 0;
@@ -60,8 +57,15 @@
         { return currentcapchannel; }
     virtual QString GetCurrentInput(void) const
         { return channelnames[GetCurrentInputNum()]; }
+    virtual int GetNextInputNum(void) const;
+    virtual QString GetNextInput(void) const
+        { return channelnames[GetNextInputNum()]; }
+    virtual QString GetNextInputStartChan(void)
+        { return inputChannel[GetNextInputNum()]; }
+    virtual QString GetInputType(const QString&, QString&) const;
     virtual QString GetOrdering(void) const
         { return channelorder; }
+    virtual QStringList GetConnectedInputs(void) const;
     /// \brief Returns true iff commercial detection is not required
     //         on current channel, for BBC, CBC, etc.
     bool IsCommercialFree(void) const { return commfree; }
@@ -76,7 +80,6 @@
     virtual bool SetChannelByDirection(ChannelChangeDirection);
 
     // Input toggling convenience methods
-    virtual bool ToggleInputs(void);
     virtual bool SwitchToInput(const QString &input);
     virtual bool SwitchToInput(const QString &input, const QString &chan);
 
@@ -115,7 +118,10 @@
     void StoreInputChannels(const QMap<int, QString> &inputChannel);
 
   protected:
-    int GetNextInput(void) const;
+    /// \brief Switches to another input on hardware, 
+    ///        and sets the channel is setstarting is true.
+    virtual bool SwitchToInput(int newcapchannel, bool setstarting) = 0;
+
     virtual int GetCardID(void) const;
     virtual bool ChangeExternalChannel(const QString &newchan);
     virtual void SetCachedATSCInfo(const QString &chan);
Index: libs/libmythtv/osd.cpp
===================================================================
--- libs/libmythtv/osd.cpp	(revision 8741)
+++ libs/libmythtv/osd.cpp	(working copy)
@@ -1896,9 +1896,9 @@
     char name[128];
     sprintf(name, "%lld-%d", number, type);
 
-    int xpos = (int)((editarrowRect.width() * 1.0 / totalframes) * number);
-    xpos = (editarrowRect.left() + xpos) * wmult;
-    int ypos = editarrowRect.top() * hmult;
+    int xtmp = (int)((editarrowRect.width() * 1.0 / totalframes) * number);
+    int xpos = (int) round((editarrowRect.left() + xtmp) * wmult);
+    int ypos = (int) round(editarrowRect.top() * hmult);
 
     osdlock.lock();
 
Index: libs/libmythtv/tv_rec.h
===================================================================
--- libs/libmythtv/tv_rec.h	(revision 8741)
+++ libs/libmythtv/tv_rec.h	(working copy)
@@ -187,8 +187,11 @@
     void ToggleChannelFavorite(void);
 
     void SetLiveRecording(int recording);
-    /// Toggles between inputs on current capture card.
-    void ToggleInputs(void)     { SetChannel("ToggleInputs"); }
+
+    QStringList GetConnectedInputs(void) const;
+    QString     GetInput(void) const;
+    QString     SetInput(QString input, uint requestType = kFlagDetect);
+
     /// Changes to a channel in the 'dir' channel change direction.
     void ChangeChannel(ChannelChangeDirection dir)
         { SetChannel(QString("NextChannel %1").arg((int)dir)); }
@@ -249,6 +252,7 @@
     HDTVRecorder *GetHDTVRecorder(void);
     DVBRecorder  *GetDVBRecorder(void);
     
+    bool CreateChannel(void);
     void InitChannel(const QString &inputname, const QString &startchannel);
     void CloseChannel(void);
     DBox2Channel *GetDBox2Channel(void);
@@ -323,7 +327,7 @@
     bool              ispip;
 
     // Configuration variables from database, based on cardid
-    GeneralDBOptions  genOpt;
+    GeneralDBOptions  genOpt, origGenOpt;
     DVBDBOptions      dvbOpt;
     FireWireDBOptions fwOpt;
     DBox2DBOptions    dboxOpt;
Index: libs/libmythtv/channelbase.cpp
===================================================================
--- libs/libmythtv/channelbase.cpp	(revision 8741)
+++ libs/libmythtv/channelbase.cpp	(working copy)
@@ -52,7 +52,7 @@
     return fTune;
 }
 
-int ChannelBase::GetNextInput(void) const
+int ChannelBase::GetNextInputNum(void) const
 {
     QMap<int, QString>::const_iterator it;
     it = channelnames.find(currentcapchannel);
@@ -80,12 +80,16 @@
     return (i<100) ? it.key() : -1;
 }
 
-bool ChannelBase::ToggleInputs(void)
+QStringList ChannelBase::GetConnectedInputs(void) const
 {
-    int nextInput = GetNextInput();
-    if (nextInput >= 0 && (nextInput != currentcapchannel))
-        return SwitchToInput(nextInput, true);
-    return true;
+    QStringList list;
+
+    QMap<int, QString>::const_iterator it = channelnames.begin();
+    for (; it != channelnames.end(); ++it)
+        if (!inputTuneTo[it.key()].isEmpty())
+            list.push_back(it.data());
+
+    return list;
 }
 
 QString ChannelBase::GetInputByNum(int capchannel) const
@@ -139,6 +143,33 @@
     return ok;
 }
 
+QString ChannelBase::GetInputType(const QString &inputname,
+                                    QString &inputdevice) const
+{
+    QString inputformat = QString::null;
+
+    MSqlQuery query(MSqlQuery::InitCon());
+    query.prepare(
+        "SELECT inputtype, inputdev "
+        "FROM cardinput "
+        "WHERE cardid    = :CARDID    AND "
+        "      inputname = :INPUTNAME");
+    query.bindValue(":CARDID",    GetCardID());
+    query.bindValue(":INPUTNAME", inputname);
+
+    if (!query.exec() || !query.isActive())
+    {
+        MythContext::DBError("GetInputFormat", query);
+    }
+    else if (query.next())
+    {
+        inputformat = query.value(0).toString();
+        inputdevice = query.value(1).toString();
+    }
+
+    return inputformat;
+}
+
 bool ChannelBase::ChangeExternalChannel(const QString &channum)
 {
     if (externalChanger[currentcapchannel].isEmpty())
Index: libs/libmythtv/channel.cpp
===================================================================
--- libs/libmythtv/channel.cpp	(revision 8741)
+++ libs/libmythtv/channel.cpp	(working copy)
@@ -276,7 +276,7 @@
 
     int inputNum = currentcapchannel;
     if (currentcapchannel < 0)
-        inputNum = GetNextInput();
+        inputNum = GetNextInputNum();
 
     QString fmt = format;
     if ((fmt == "Default") || format.isEmpty())
Index: programs/mythbackend/encoderlink.h
===================================================================
--- programs/mythbackend/encoderlink.h	(revision 8741)
+++ programs/mythbackend/encoderlink.h	(working copy)
@@ -76,7 +76,9 @@
     void StopLiveTV(void);
     void PauseRecorder(void);
     void SetLiveRecording(int);
-    void ToggleInputs(void);
+    QStringList GetConnectedInputs(void) const;
+    QString GetInput(void) const;
+    QString SetInput(QString);
     void ToggleChannelFavorite(void);
     void ChangeChannel(int channeldirection);
     void SetChannel(const QString &name);
Index: programs/mythbackend/mainserver.cpp
===================================================================
--- programs/mythbackend/mainserver.cpp	(revision 8741)
+++ programs/mythbackend/mainserver.cpp	(working copy)
@@ -2473,11 +2473,27 @@
         enc->SetLiveRecording(recording);
         retlist << "ok";
     }
-    else if (command == "TOGGLE_INPUTS")
+    else if (command == "GET_CONNECTED_INPUTS")
     {
-        enc->ToggleInputs();
-        retlist << "ok";
+        QStringList ret = enc->GetConnectedInputs();
+        if (ret.empty())
+            retlist << "EMPTY_LIST";
+        else
+            retlist += ret;
     }
+    else if (command == "GET_INPUT")
+    {
+        QString ret = enc->GetInput();
+        ret = (ret.isEmpty()) ? "UNKNOWN" : ret;
+        retlist << ret;
+    }
+    else if (command == "SET_INPUT")
+    {
+        QString input = slist[2];
+        QString ret   = enc->SetInput(input);
+        ret = (ret.isEmpty()) ? "UNKNOWN" : ret;
+        retlist << ret;
+    }
     else if (command == "TOGGLE_CHANNEL_FAVORITE")
     {
         enc->ToggleChannelFavorite();
Index: programs/mythbackend/encoderlink.cpp
===================================================================
--- programs/mythbackend/encoderlink.cpp	(revision 8741)
+++ programs/mythbackend/encoderlink.cpp	(working copy)
@@ -654,20 +654,58 @@
         VERBOSE(VB_IMPORTANT, "Should be local only query: SetLiveRecording");
 }
 
-/** \fn EncoderLink::ToggleInputs(void)
- *  \brief Tells TVRec's recorder to change to the next input.
+/** \fn EncoderLink::GetConnectedInputs(void) const
+ *  \brief Returns TVRec's recorders connected inputs.
  *         <b>This only works on local recorders.</b>
  *
- *   You must call PauseRecorder(void) before calling this.
+ *  \sa TVRec::GetConnectedInputs(void) const
  */
-void EncoderLink::ToggleInputs(void)
+QStringList EncoderLink::GetConnectedInputs(void) const
 {
+    QStringList list;
+
     if (local)
-        tv->ToggleInputs();
+        list = tv->GetConnectedInputs();
     else
-        VERBOSE(VB_IMPORTANT, "Should be local only query: ToggleInputs");
+        VERBOSE(VB_IMPORTANT, "Should be local only query: GetConnectedInputs");
+
+    return list;
 }
 
+/** \fn EncoderLink::GetInput(void) const
+ *  \brief Returns TVRec's recorders current input.
+ *         <b>This only works on local recorders.</b>
+ *
+ *  \sa TVRec::GetInput(void) const
+ */
+QString EncoderLink::GetInput(void) const
+{
+    if (local)
+        return tv->GetInput();
+
+    VERBOSE(VB_IMPORTANT, "Should be local only query: GetInput");
+    return QString::null;
+}
+
+/** \fn EncoderLink::SetInput(QString)
+ *  \brief Tells TVRec's recorder to change to the specified input.
+ *         <b>This only works on local recorders.</b>
+ *
+ *   You must call PauseRecorder(void) before calling this.
+ *
+ *  \param input Input to switch to, or "SwitchToNectInput".
+ *  \return input we have switched to
+ *  \sa TVRec::SetInput(QString)
+ */
+QString EncoderLink::SetInput(QString input)
+{
+    if (local)
+        return tv->SetInput(input);
+
+    VERBOSE(VB_IMPORTANT, "Should be local only query: SetInput");
+    return QString::null;
+}
+
 /** \fn EncoderLink::ToggleChannelFavorite(void)
  *  \brief Toggles whether the current channel should be on our favorites list.
  *         <b>This only works on local recorders.</b>
