Index: TVLibrary/SetupTv/Dialogs/FormAnalogTuningDetail.Designer.cs
===================================================================
--- TVLibrary/SetupTv/Dialogs/FormAnalogTuningDetail.Designer.cs	(revision 27923)
+++ TVLibrary/SetupTv/Dialogs/FormAnalogTuningDetail.Designer.cs	(working copy)
@@ -240,7 +240,10 @@
             "RGB #3",
             "YRYBY #1",
             "YRYBY #2",
-            "YRYBY #3"});
+            "YRYBY #3",
+            "HDMI #1",
+            "HDMI #2",
+            "HDMI #3"});
       this.comboBoxVideoSource.Location = new System.Drawing.Point(93, 32);
       this.comboBoxVideoSource.Name = "comboBoxVideoSource";
       this.comboBoxVideoSource.Size = new System.Drawing.Size(258, 21);
Index: TVLibrary/SetupTv/Sections/CardAnalog.cs
===================================================================
--- TVLibrary/SetupTv/Sections/CardAnalog.cs	(revision 27923)
+++ TVLibrary/SetupTv/Sections/CardAnalog.cs	(working copy)
@@ -1538,6 +1538,72 @@
         layer.MapChannelToCard(card, dbChannel, false);
         layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels);
       }
+      if (videoPinMap.ContainsKey(AnalogChannel.VideoInputType.HdmiInput1))
+      {
+        string channelName = "HDMI#1 on " + card.IdCard;
+        IList<TuningDetail> tuningDetails = layer.GetTuningDetailsByName(channelName, 0);
+        if (tuningDetails != null && tuningDetails.Count > 0)
+        {
+          dbChannel = tuningDetails[0].ReferencedChannel();
+        }
+        else
+        {
+          dbChannel = layer.AddNewChannel(channelName);
+        }
+        dbChannel.IsTv = true;
+        dbChannel.Persist();
+        tuningDetail = new AnalogChannel();
+        tuningDetail.IsTv = true;
+        tuningDetail.Name = dbChannel.DisplayName;
+        tuningDetail.VideoSource = AnalogChannel.VideoInputType.HdmiInput1;
+        layer.AddTuningDetails(dbChannel, tuningDetail);
+        layer.MapChannelToCard(card, dbChannel, false);
+        layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels);
+      }
+      if (videoPinMap.ContainsKey(AnalogChannel.VideoInputType.HdmiInput2))
+      {
+        string channelName = "HDMI#2 on " + card.IdCard;
+        IList<TuningDetail> tuningDetails = layer.GetTuningDetailsByName(channelName, 0);
+        if (tuningDetails != null && tuningDetails.Count > 0)
+        {
+          dbChannel = tuningDetails[0].ReferencedChannel();
+        }
+        else
+        {
+          dbChannel = layer.AddNewChannel(channelName);
+        }
+        dbChannel.IsTv = true;
+        dbChannel.Persist();
+        tuningDetail = new AnalogChannel();
+        tuningDetail.IsTv = true;
+        tuningDetail.Name = dbChannel.DisplayName;
+        tuningDetail.VideoSource = AnalogChannel.VideoInputType.HdmiInput2;
+        layer.AddTuningDetails(dbChannel, tuningDetail);
+        layer.MapChannelToCard(card, dbChannel, false);
+        layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels);
+      }
+      if (videoPinMap.ContainsKey(AnalogChannel.VideoInputType.HdmiInput3))
+      {
+        string channelName = "HDMI#3 on " + card.IdCard;
+        IList<TuningDetail> tuningDetails = layer.GetTuningDetailsByName(channelName, 0);
+        if (tuningDetails != null && tuningDetails.Count > 0)
+        {
+          dbChannel = tuningDetails[0].ReferencedChannel();
+        }
+        else
+        {
+          dbChannel = layer.AddNewChannel(channelName);
+        }
+        dbChannel.IsTv = true;
+        dbChannel.Persist();
+        tuningDetail = new AnalogChannel();
+        tuningDetail.IsTv = true;
+        tuningDetail.Name = dbChannel.DisplayName;
+        tuningDetail.VideoSource = AnalogChannel.VideoInputType.HdmiInput3;
+        layer.AddTuningDetails(dbChannel, tuningDetail);
+        layer.MapChannelToCard(card, dbChannel, false);
+        layer.AddChannelToGroup(dbChannel, TvConstants.TvGroupNames.AllChannels);
+      }
       MessageBox.Show(this, "Channels added.");
     }
 
Index: TVLibrary/TvLibrary.Interfaces/Implementations/Channels/AnalogChannel.cs
===================================================================
--- TVLibrary/TvLibrary.Interfaces/Implementations/Channels/AnalogChannel.cs	(revision 27923)
+++ TVLibrary/TvLibrary.Interfaces/Implementations/Channels/AnalogChannel.cs	(working copy)
@@ -88,7 +88,19 @@
       /// <summary>
       /// RGB input #3
       /// </summary>
-      YRYBYInput3
+      YRYBYInput3,
+      /// <summary>
+      /// HDMI input #1
+      /// </summary>
+      HdmiInput1,
+      /// <summary>
+      /// HDMI input #2
+      /// </summary>
+      HdmiInput2,
+      /// <summary>
+      /// HDMI input #3
+      /// </summary>
+      HdmiInput3
     }
 
     /// <summary>
Index: TVLibrary/TVLibrary/Implementations/Analog/Components/Crossbar.cs
===================================================================
--- TVLibrary/TVLibrary/Implementations/Analog/Components/Crossbar.cs	(revision 27923)
+++ TVLibrary/TVLibrary/Implementations/Analog/Components/Crossbar.cs	(working copy)
@@ -470,6 +470,7 @@
       int videoSvhsNr = 0;
       int videoYrYbYNr = 0;
       int videoRgbNr = 0;
+      int videoHdmiNr = 0;
       for (int i = 0; i < inputs; ++i)
       {
         _crossBarFilter.get_CrossbarPinInfo(true, i, out relatedPinIndex, out connectorType);
@@ -600,6 +601,24 @@
                 break;
             }
             break;
+          case PhysicalConnectorType.Video_SerialDigital:
+            videoHdmiNr++;
+            switch (videoHdmiNr)
+            {
+              case 1:
+                _videoPinMap.Add(AnalogChannel.VideoInputType.HdmiInput1, i);
+                _videoPinRelatedAudioMap.Add(AnalogChannel.VideoInputType.HdmiInput1, relatedPinIndex);
+                break;
+              case 2:
+                _videoPinMap.Add(AnalogChannel.VideoInputType.HdmiInput2, i);
+                _videoPinRelatedAudioMap.Add(AnalogChannel.VideoInputType.HdmiInput2, relatedPinIndex);
+                break;
+              case 3:
+                _videoPinMap.Add(AnalogChannel.VideoInputType.HdmiInput3, i);
+                _videoPinRelatedAudioMap.Add(AnalogChannel.VideoInputType.HdmiInput3, relatedPinIndex);
+                break;
+            }
+            break;
         }
       }
     }
Index: TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs
===================================================================
--- TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs	(revision 27923)
+++ TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs	(working copy)
@@ -154,13 +154,52 @@
     /// <returns><c>true</c> if PMT was found, otherwise <c>false</c></returns>
     protected override bool WaitForPMT()
     {
+      Log.Log.WriteFile("HDPVR: sleeping while waiting for stable PMT...");
       SetupPmtGrabber(PMT_PID, SERVICE_ID);
+      _pmtRequested = true;
       if (!_eventPMT.WaitOne(_parameters.TimeOutPMT * 1000, true))
       {
         return false;
       }
+      return handlePmt();
+    }
 
-      // Once we receive PMT...
+    /// <summary>
+    /// Stub override to allow inherritance from TvDvbChannel.
+    /// </summary>
+    protected override bool SendPmtToCam(out bool updatePids, out int waitInterval)
+    {
+      updatePids = false;
+      waitInterval = 0;
+      return true;
+    }
+
+    #endregion
+
+    #region IPMTCallback Members
+
+    /// <summary>
+    /// Called when the PMT has been received.
+    /// </summary>
+    /// <returns></returns>
+    public override int OnPMTReceived(int pmtPid)
+    {
+      Log.Log.WriteFile("HDPVR: OnPMTReceived() subch:{0} pid 0x{1:X}", _subChannelId, pmtPid);
+      _pmtPid = pmtPid;
+      if (_eventPMT != null)
+      {
+        _eventPMT.Set();
+      }
+      if (!_pmtRequested)
+      {
+        handlePmt();
+      }
+      _pmtRequested = false;
+      return 0;
+    }
+
+    private bool handlePmt()
+    {
       IntPtr pmtMem = Marshal.AllocCoTaskMem(4096); // max. size for pmt
       try
       {
@@ -196,35 +235,6 @@
       }
     }
 
-    /// <summary>
-    /// Stub override to allow inherritance from TvDvbChannel.
-    /// </summary>
-    protected override bool SendPmtToCam(out bool updatePids, out int waitInterval)
-    {
-      updatePids = false;
-      waitInterval = 0;
-      return true;
-    }
-
     #endregion
-
-    #region IPMTCallback Members
-
-    /// <summary>
-    /// Called when the PMT has been received.
-    /// </summary>
-    /// <returns></returns>
-    public override int OnPMTReceived(int pmtPid)
-    {
-      Log.Log.WriteFile("HDPVR: OnPMTReceived() subch:{0} pid 0x{1:X}", _subChannelId, pmtPid);
-      if (_eventPMT != null)
-      {
-        _eventPMT.Set();
-      }
-      _pmtPid = pmtPid;
-      return 0;
-    }
-
-    #endregion
   }
 }
\ No newline at end of file
Index: TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs
===================================================================
--- TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs	(revision 27923)
+++ TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs	(working copy)
@@ -808,28 +808,6 @@
     }
 
     /// <summary>
-    /// Sets up the cross bar.
-    /// </summary>
-    /// <param name="vmode">The crossbar video mode.</param>
-    /// <param name="amode">The crossbar audio mode.</param>
-    private void SetupCrossBar(AnalogChannel.VideoInputType vmode, AnalogChannel.AudioInputType amode)
-    {
-      Log.Log.WriteFile("HDPVR: SetupCrossBar:{0} / {1}", vmode, amode);
-      IAMCrossbar crossBarFilter = _filterCrossBar as IAMCrossbar;
-      if (crossBarFilter != null)
-      {
-        if (_videoPinMap.ContainsKey(vmode))
-        {
-          crossBarFilter.Route(_videoOutPinIndex, _videoPinMap[vmode]);
-        }
-        if (_audioPinMap.ContainsKey(amode))
-        {
-          crossBarFilter.Route(_audioOutPinIndex, _audioPinMap[amode]);
-        }
-      }
-    }
-
-    /// <summary>
     /// Method which starts the graph
     /// </summary>
     public override void RunGraph(int subChannel)
@@ -881,22 +859,40 @@
 
     private void PerformTuning(IChannel channel)
     {
+      Log.Log.WriteFile("HDPVR: Tune");
       AnalogChannel analogChannel = channel as AnalogChannel;
       if (analogChannel == null)
       {
         throw new NullReferenceException();
       }
-      if (_previousChannel != null)
+
+      // Set up the crossbar.
+      IAMCrossbar crossBarFilter = _filterCrossBar as IAMCrossbar;
+
+      // Video
+      if ((_previousChannel == null || _previousChannel.VideoSource != analogChannel.VideoSource) &&
+        _videoPinMap.ContainsKey(analogChannel.VideoSource))
       {
-        if (_previousChannel.VideoSource != analogChannel.VideoSource)
+        Log.Log.WriteFile("HDPVR:   video input -> {0}", analogChannel.VideoSource);
+        crossBarFilter.Route(_videoOutPinIndex, _videoPinMap[analogChannel.VideoSource]);
+      }
+
+      // Audio
+      if (analogChannel.AudioSource == AnalogChannel.AudioInputType.Automatic)
+      {
+        if (_videoPinRelatedAudioMap.ContainsKey(analogChannel.VideoSource))
         {
-          SetupCrossBar(analogChannel.VideoSource, analogChannel.AudioSource);
+          Log.Log.WriteFile("HDPVR:   audio input -> (auto)");
+          crossBarFilter.Route(_audioOutPinIndex, _videoPinRelatedAudioMap[analogChannel.VideoSource]);
         }
       }
-      else
+      else if ((_previousChannel == null || _previousChannel.AudioSource != analogChannel.AudioSource) &&
+        _audioPinMap.ContainsKey(analogChannel.AudioSource))
       {
-        SetupCrossBar(analogChannel.VideoSource, analogChannel.AudioSource);
+        Log.Log.WriteFile("HDPVR:   audio input -> {0}", analogChannel.AudioSource);
+        crossBarFilter.Route(_audioOutPinIndex, _audioPinMap[analogChannel.AudioSource]);
       }
+
       _lastSignalUpdate = DateTime.MinValue;
       _tunerLocked = false;
       _previousChannel = analogChannel;
@@ -945,6 +941,7 @@
         int videoSvhsNr = 0;
         int videoYrYbYNr = 0;
         int videoRgbNr = 0;
+        int videoHdmiNr = 0;
         for (int i = 0; i < inputs; ++i)
         {
           crossBarFilter.get_CrossbarPinInfo(true, i, out relatedPinIndex, out connectorType);
@@ -1075,6 +1072,24 @@
                   break;
               }
               break;
+            case PhysicalConnectorType.Video_SerialDigital:
+              videoHdmiNr++;
+              switch (videoHdmiNr)
+              {
+                case 1:
+                  _videoPinMap.Add(AnalogChannel.VideoInputType.HdmiInput1, i);
+                  _videoPinRelatedAudioMap.Add(AnalogChannel.VideoInputType.HdmiInput1, relatedPinIndex);
+                  break;
+                case 2:
+                  _videoPinMap.Add(AnalogChannel.VideoInputType.HdmiInput2, i);
+                  _videoPinRelatedAudioMap.Add(AnalogChannel.VideoInputType.HdmiInput2, relatedPinIndex);
+                  break;
+                case 3:
+                  _videoPinMap.Add(AnalogChannel.VideoInputType.HdmiInput3, i);
+                  _videoPinRelatedAudioMap.Add(AnalogChannel.VideoInputType.HdmiInput3, relatedPinIndex);
+                  break;
+              }
+              break;
           }
         }
       }
