Index: TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs
===================================================================
--- TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs	(revision 27798)
+++ TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/HDPVRChannel.cs	(working copy)
@@ -26,62 +26,68 @@
 using TvLibrary.Interfaces;
 using TvLibrary.Implementations.Helper;
 using TvLibrary.Interfaces.Analyzer;
+using TvLibrary.Implementations.DVB;
+using TvLibrary.Implementations.DVB.Structures;
+using TvLibrary.Channels;
 
 namespace TvLibrary.Implementations.Analog
 {
   /// <summary>
   /// Implementation of <see cref="T:TvLibrary.Interfaces.ITVCard"/> which handles analog tv cards
   /// </summary>
-  public class HDPVRChannel : BaseSubChannel, ITvSubChannel, IVideoAudioObserver, IPMTCallback
+  public class HDPVRChannel : TvDvbChannel, ITvSubChannel, IVideoAudioObserver, IPMTCallback
   {
+    // The HDPVR delivers a DVB stream with a single service on a fixed
+    // service ID with a fixed PMT PID.
+    private const int HDPVR_SERVICE_ID = 1;
+    private const int HDPVR_PMT_PID = 0x100;
+
     #region variables
 
     private readonly TvCardHDPVR _card;
-    private readonly IBaseFilter _filterTsWriter;
-    private readonly ITsFilter _tsFilterInterface;
-    private Int32 _pmtPid;
-    private const int _serviceID = 1;
-    private Int32 _pmtVersion = -1;
-    private int _pmtLength;
-    private byte[] _pmtData;
-    private bool _graphRunning;
 
     #endregion
 
     /// <summary>
     /// Initializes a new instance of the <see cref="AnalogSubChannel"/> class.
     /// </summary>
-    public HDPVRChannel(TvCardHDPVR card, Int32 subchannelId, IChannel channel, IBaseFilter filterTsWriter)
+    public HDPVRChannel(TvCardHDPVR card, Int32 subchannelId, IBaseFilter filterTsWriter, IFilterGraph2 graphBuilder)
     {
+      _eventPMT = new ManualResetEvent(false);
+      _graphState = GraphState.Created;
+      _graphBuilder = graphBuilder;
+      _channelInfo = new ChannelInfo();
+      _pmtPid = -1;
+      _subChannelIndex = -1;
+
+      // Keep a reference to the card for quality control.
       _card = card;
+
+      _tsFilterInterface = (ITsFilter)filterTsWriter;
+      _tsFilterInterface.AddChannel(ref _subChannelIndex);
       _subChannelId = subchannelId;
-      _currentChannel = channel;
-      _filterTsWriter = filterTsWriter;
-      _hasTeletext = false;
-      _tsFilterInterface = (ITsFilter)_filterTsWriter;
-      _tsFilterInterface.AddChannel(ref _subChannelId);
+      _timeshiftFileName = "";
+      _recordingFileName = "";
       _pmtData = null;
       _pmtLength = 0;
+
+      _grabTeletext = false;
+      _mdplugs = null;
     }
 
-    #region tuning and graph methods
-
     /// <summary>
-    /// Should be called before tuning to a new channel
-    /// resets the state
+    /// Destructor
     /// </summary>
-    public override void OnBeforeTune()
+    ~HDPVRChannel()
     {
-      Log.Log.WriteFile("HDPVR: subch:{0} OnBeforeTune", _subChannelId);
-      if (IsTimeShifting)
+      if (_eventPMT != null)
       {
-        if (_subChannelId >= 0)
-        {
-          _tsFilterInterface.TimeShiftPause(_subChannelId, 1);
-        }
+        _eventPMT.Close();
       }
     }
 
+    #region tuning and graph method overrides
+
     /// <summary>
     /// Should be called when the graph is tuned to the new channel
     /// resets the state
@@ -89,315 +95,98 @@
     public override void OnAfterTune()
     {
       Log.Log.WriteFile("HDPVR: subch:{0} OnAfterTune", _subChannelId);
-      if (IsTimeShifting && _subChannelId >= 0)
-      {
-        _tsFilterInterface.TimeShiftPause(_subChannelId, 0);
-
-        //hack
-        OnNotify(PidType.Audio);
-        OnNotify(PidType.Video);
-      }
     }
 
     /// <summary>
-    /// Should be called when the graph is about to start
-    /// Resets the state 
-    /// If graph is already running, starts the pmt grabber to grab the
-    /// pmt for the new channel
+    /// Stop recording
     /// </summary>
-    public override void OnGraphStart()
+    /// <returns></returns>
+    protected override void OnStopRecording()
     {
-      Log.Log.WriteFile("HDPVR: subch:{0} OnGraphStart", _subChannelId);
-
-      if (SetupPmtGrabber(256, _serviceID))
+      base.OnStopRecording();
+      if (_card.SupportsQualityControl && IsTimeShifting)
       {
-        DateTime dtNow = DateTime.Now;
-        while (_pmtVersion < 0)
-        {
-          Log.Log.Write("subch:{0} wait for pmt", _subChannelId);
-          Thread.Sleep(20);
-          TimeSpan ts = DateTime.Now - dtNow;
-          if (ts.TotalMilliseconds >= 10)
-          {
-            Log.Log.Debug("Timedout waiting for PMT after {0} seconds. Increase the PMT timeout value?", ts.TotalSeconds);
-            break;
-          }
-        }
+        _card.Quality.StartPlayback();
       }
     }
 
-    /// <summary>
-    /// Instructs the ts analyzer filter to start grabbing the PMT
-    /// </summary>
-    /// <param name="pmtPid">pid of the PMT</param>
-    /// <param name="serviceId">The service id.</param>
-    protected bool SetupPmtGrabber(int pmtPid, int serviceId)
+    protected override bool WaitForPMT()
     {
-      Log.Log.Info("subch:{0} SetupPmtGrabber:pid {1:X} sid:{2:X}", _subChannelId, pmtPid, serviceId);
-      if (pmtPid < 0)
-        return false;
-      if (pmtPid == _pmtPid)
-        return false;
-      _pmtVersion = -1;
-      _pmtPid = pmtPid;
-      Log.Log.Write("subch:{0} set pmt grabber pmt:{1:X} sid:{2:X}", _subChannelId, pmtPid, serviceId);
-      _tsFilterInterface.PmtSetCallBack(_subChannelId, this);
-      _tsFilterInterface.PmtSetPmtPid(_subChannelId, pmtPid, serviceId);
-
-      OnAfterTuneEvent();
-      return true;
-    }
-
-    /// <summary>
-    /// Should be called when the graph has been started
-    /// sets up the pmt grabber to grab the pmt of the channel
-    /// </summary>
-    public override void OnGraphStarted()
-    {
-      Log.Log.WriteFile("HDPVR: subch:{0} OnGraphStarted", _subChannelId);
-      _graphRunning = true;
-      _dateTimeShiftStarted = DateTime.MinValue;
-      SetupPmtGrabber(_pmtPid, _serviceID);
-      //_pmtTimer.Enabled = true;
-      while (_pmtVersion < 0)
+      if (!SetupPmtGrabber(HDPVR_PMT_PID, HDPVR_SERVICE_ID))
       {
-        Log.Log.Write("subch:{0} wait for pmt:{1:X}", _subChannelId, _pmtPid);
-        Thread.Sleep(20);
+        // Already "tuned" and PMT received.
+        return true;
       }
-    }
 
-    /// <summary>
-    /// Should be called when graph is about to stop.
-    /// stops any timeshifting/recording on this channel
-    /// </summary>
-    public override void OnGraphStop()
-    {
-      if (_tsFilterInterface != null)
+      if (!_eventPMT.WaitOne(_parameters.TimeOutPMT * 1000, true))
       {
-        _tsFilterInterface.RecordStopRecord(_subChannelId);
-        _tsFilterInterface.TimeShiftStop(_subChannelId);
+        return false;
       }
-    }
 
-    /// <summary>
-    /// should be called when graph has been stopped
-    /// Resets the graph state
-    /// </summary>
-    public override void OnGraphStopped() {}
-
-    #endregion
-
-    #region Timeshifting - Recording methods
-
-    /// <summary>
-    /// sets the filename used for timeshifting
-    /// </summary>
-    /// <param name="fileName">timeshifting filename</param>
-    protected override bool OnStartTimeShifting(string fileName)
-    {
-      _timeshiftFileName = fileName;
-      Log.Log.WriteFile("HDPVR: SetTimeShiftFileName:{0}", fileName);
-      Log.Log.WriteFile("HDPVR: SetTimeShiftFileName: _subChannelId {0}", _subChannelId);
-      ScanParameters parameters = _card.Parameters;
-      _tsFilterInterface.TimeShiftSetParams(_subChannelId, parameters.MinimumFiles, parameters.MaximumFiles,
-                                            parameters.MaximumFileSize);
-      _tsFilterInterface.TimeShiftSetTimeShiftingFileNameW(_subChannelId, fileName);
-
-      if (CurrentChannel == null)
+      // Once we receive PMT...
+      IntPtr pmtMem = Marshal.AllocCoTaskMem(4096); // max. size for pmt
+      try
       {
-        Log.Log.Error("CurrentChannel is null when trying to start timeshifting");
-        return false;
-      }
+        _pmtLength = _tsFilterInterface.PmtGetPMTData(_subChannelIndex, pmtMem);
+        if (_pmtLength < 6)
+        {
+          return false;
+        }
 
-      //  Set the channel type (0=tv, 1=radio)
-      _tsFilterInterface.TimeShiftSetChannelType(_subChannelId, (CurrentChannel.IsTv ? 0 : 1));
+        // Check the program number.
+        _pmtData = new byte[_pmtLength];
+        Marshal.Copy(pmtMem, _pmtData, 0, _pmtLength);
+        int version = ((_pmtData[5] >> 1) & 0x1F);
+        int pmtProgramNumber = (_pmtData[3] << 8) + _pmtData[4];
+        Log.Log.Info("PMT 0x{0:X}, 0x{1:X}", pmtProgramNumber, version);
+        if (pmtProgramNumber != HDPVR_SERVICE_ID)
+        {
+          throw new TvException("HDPVRChannel.WaitForPMT: PMT program doesn't match HDPVR service ID");
+        }
 
-      _tsFilterInterface.TimeShiftPause(_subChannelId, 1);
-      _tsFilterInterface.TimeShiftSetPmtPid(_subChannelId, 0x0100, 1, _pmtData, _pmtLength);
-      _tsFilterInterface.AnalyzerSetVideoPid(_subChannelId, 0x1011);
-      _tsFilterInterface.AnalyzerSetAudioPid(_subChannelId, 0x1100);
-      _tsFilterInterface.TimeShiftPause(_subChannelId, 0);
-
-      _tsFilterInterface.SetVideoAudioObserver(_subChannelId, this);
-      _tsFilterInterface.TimeShiftStart(_subChannelId);
-      _dateTimeShiftStarted = DateTime.Now;
-
-      return true;
-    }
-
-    /// <summary>
-    /// Stops timeshifting
-    /// </summary>
-    /// <returns></returns>
-    protected override void OnStopTimeShifting()
-    {
-      Log.Log.WriteFile("HDPVR: StopTimeShifting()");
-      _tsFilterInterface.SetVideoAudioObserver(_subChannelId, null);
-      _tsFilterInterface.TimeShiftStop(_subChannelId);
-    }
-
-    /// <summary>
-    /// Starts recording
-    /// </summary>
-    /// <param name="fileName">filename to which to recording should be saved</param>
-    /// <returns></returns>
-    protected override void OnStartRecording(string fileName)
-    {
-      _recordingFileName = fileName;
-      _tsFilterInterface.RecordSetRecordingFileNameW(_subChannelId, fileName);
-      _tsFilterInterface.RecordSetPmtPid(_subChannelId, 0x0100, 1, _pmtData, _pmtLength);
-      _startRecording = true;
-      _tsFilterInterface.RecorderSetVideoAudioObserver(_subChannelId, this);
-      int hr = _tsFilterInterface.RecordStartRecord(_subChannelId);
-      if (hr != 0)
-      {
-        Log.Log.Error("subch:{0} StartRecord failed:{1:X}", _subChannelId, hr);
+        // Get the program PIDs.
+        _pmtVersion = version;
+        _channelInfo = new ChannelInfo();
+        _channelInfo.DecodePmt(_pmtData);
+        _channelInfo.serviceID = HDPVR_SERVICE_ID;
+        _channelInfo.network_pmt_PID = HDPVR_PMT_PID;
+        SetMpegPidMapping(_channelInfo);
+        return true;
       }
-      _graphState = GraphState.Recording;
-    }
-
-    /// <summary>
-    /// Stop recording
-    /// </summary>
-    /// <returns></returns>
-    protected override void OnStopRecording()
-    {
-      Log.Log.WriteFile("HDPVR: StopRecord()");
-      _tsFilterInterface.RecordStopRecord(_subChannelId);
-      if (_card.SupportsQualityControl && IsTimeShifting)
+      finally
       {
-        _card.Quality.StartPlayback();
+        Marshal.FreeCoTaskMem(pmtMem);
       }
     }
 
     /// <summary>
-    /// Returns the position in the current timeshift file and the id of the current timeshift file
+    /// Stub override to allow inherritance from TvDvbChannel.
     /// </summary>
-    /// <param name="position">The position in the current timeshift buffer file</param>
-    /// <param name="bufferId">The id of the current timeshift buffer file</param>
-    protected override void OnGetTimeShiftFilePosition(ref Int64 position, ref long bufferId)
+    protected override bool SendPmtToCam(out bool updatePids, out int waitInterval)
     {
-      _tsFilterInterface.TimeShiftGetCurrentFilePosition(_subChannelId, out position, out bufferId);
+      updatePids = false;
+      waitInterval = 0;
+      return true;
     }
 
     #endregion
 
-    #region audio streams
+    #region IPMTCallback Members
 
     /// <summary>
-    /// returns the list of available audio streams
-    /// </summary>
-    public override List<IAudioStream> AvailableAudioStreams
-    {
-      get { return null; }
-    }
-
-    /// <summary>
-    /// get/set the current selected audio stream
-    /// </summary>
-    public override IAudioStream CurrentAudioStream
-    {
-      get { return null; }
-      set { }
-    }
-
-    #endregion
-
-    #region video stream
-
-    /// <summary>
-    /// Returns true when unscrambled audio/video is received otherwise false
-    /// </summary>
-    /// <returns>true of false</returns>
-    public override bool IsReceivingAudioVideo
-    {
-      get { return true; }
-    }
-
-    /// <summary>
-    /// Returns the video format (always returns MPEG2). 
-    /// </summary>
-    /// <value>The number of channels decrypting.</value>
-    public override IVideoStream GetCurrentVideoStream
-    {
-      get
-      {
-        VideoStream stream = new VideoStream();
-        return stream;
-      }
-    }
-
-    #endregion
-
-    #region teletext
-
-    /// <summary>
-    /// A derrived class should activate or deactivate the teletext grabbing on the tv card.
-    /// </summary>
-    protected override void OnGrabTeletext() {}
-
-    #endregion
-
-    #region OnDecompose
-
-    /// <summary>
-    /// Decomposes this subchannel
-    /// </summary>
-    protected override void OnDecompose()
-    {
-      if (_tsFilterInterface != null)
-      {
-        _tsFilterInterface.DeleteChannel(_subChannelId);
-      }
-    }
-
-    #endregion
-
-    /// <summary>
     /// Called when the PMT has been received.
     /// </summary>
     /// <returns></returns>
     public int OnPMTReceived(int pmtPid)
     {
-      IntPtr pmtMem = Marshal.AllocCoTaskMem(4096); // max. size for pmt
-      _pmtLength = _tsFilterInterface.PmtGetPMTData(_subChannelId, pmtMem);
-      if (_pmtLength > 6)
+      Log.Log.WriteFile("subch:{0} OnPMTReceived() pid 0x{1:X}", _subChannelId, pmtPid);
+      if (_eventPMT != null)
       {
-        _pmtData = new byte[_pmtLength];
+        _eventPMT.Set();
       }
-
-      Marshal.Copy(pmtMem, _pmtData, 0, _pmtLength);
-      Marshal.FreeCoTaskMem(pmtMem);
-
-      _pmtVersion++;
-
-      try
-      {
-        Log.Log.WriteFile("subch:{0} OnPMTReceived() {1}", _subChannelId, _graphRunning);
-        if (_graphRunning == false)
-          return 0;
-        _pmtVersion++;
-      }
-      catch (Exception ex)
-      {
-        Log.Log.Write(ex);
-      }
-
       return 0;
     }
 
-    ///<summary>
-    /// Called when a pid is detected
-    ///</summary>
-    ///<param name="pidType">The pid type</param>
-    ///<returns>Error code</returns>
-    public new int OnNotify(PidType pidType)
-    {
-      if (pidType == PidType.Video)
-      {
-        Thread.Sleep(1000);
-      }
-      return base.OnNotify(pidType);
-    }
+    #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 27798)
+++ TVLibrary/TVLibrary/Implementations/Analog/Graphs/HDPVR/TVCardHDPVR.cs	(working copy)
@@ -28,6 +28,7 @@
 using TvLibrary.Interfaces;
 using TvLibrary.Implementations.DVB;
 using TvLibrary.Implementations.Helper;
+using TvLibrary.Channels;
 
 namespace TvLibrary.Implementations.Analog
 {
@@ -313,7 +314,9 @@
     {
       int id = _subChannelId++;
       Log.Log.Info("HDPVR:GetNewSubChannel:{0} #{1}", _mapSubChannels.Count, id);
-      HDPVRChannel subChannel = new HDPVRChannel(this, id, channel, _filterTsWriter);
+      HDPVRChannel subChannel = new HDPVRChannel(this, id, _filterTsWriter, _graphBuilder);
+      subChannel.Parameters = Parameters;
+      subChannel.CurrentChannel = channel;
       _mapSubChannels[id] = subChannel;
       return id;
     }
@@ -818,11 +821,12 @@
       {
         _mapSubChannels[subChannel].AfterTuneEvent -= new BaseSubChannel.OnAfterTuneDelegate(OnAfterTuneEvent);
         _mapSubChannels[subChannel].AfterTuneEvent += new BaseSubChannel.OnAfterTuneDelegate(OnAfterTuneEvent);
-        _mapSubChannels[subChannel].OnGraphStarted();
+        _mapSubChannels[subChannel].OnGraphStart();
       }
 
       if (graphRunning)
       {
+        Log.Log.Write("HDPVR: Graph already running");
         return;
       }
 
Index: TVLibrary/TVLibrary/Implementations/BaseSubChannel.cs
===================================================================
--- TVLibrary/TVLibrary/Implementations/BaseSubChannel.cs	(revision 27798)
+++ TVLibrary/TVLibrary/Implementations/BaseSubChannel.cs	(working copy)
@@ -370,6 +370,7 @@
           Log.Log.Info("Unknown subch:{0} Started recording", _subChannelId);
         }
 
+        _dateRecordingStarted = DateTime.Now;
         _graphState = GraphState.Recording;
       }
       catch (Exception e)
Index: TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvDvbChannel.cs
===================================================================
--- TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvDvbChannel.cs	(revision 27798)
+++ TVLibrary/TVLibrary/Implementations/DVB/Graphs/TvDvbChannel.cs	(working copy)
@@ -64,6 +64,16 @@
     protected int _pmtPid = -1;
 
     /// <summary>
+    /// PMT data
+    /// </summary>
+    protected byte[] _pmtData;
+
+    /// <summary>
+    /// PMT data length
+    /// </summary>
+    protected int _pmtLength;
+
+    /// <summary>
     /// Channel Info
     /// </summary>
     protected ChannelInfo _channelInfo;
@@ -91,18 +101,11 @@
     /// set to true to enable PAT lookup of PMT
     private bool alwaysUsePATLookup = DebugSettings.UsePATLookup;
 
-    #region teletext
-
-    private int _pmtLength;
-    private byte[] _pmtData;
-
     #endregion
 
-    #endregion
-
     #region events
 
-    private ManualResetEvent _eventPMT; // gets signaled when PMT arrives
+    protected ManualResetEvent _eventPMT; // gets signaled when PMT arrives
     private ManualResetEvent _eventCA; // gets signaled when CA arrives    
 
     #endregion
@@ -111,8 +114,7 @@
 
     private readonly ConditionalAccess _conditionalAccess;
     private readonly IBaseFilter _filterTIF;
-    private readonly IBaseFilter _filterTsWriter;
-    private readonly IFilterGraph2 _graphBuilder;
+    protected IFilterGraph2 _graphBuilder;
 
     #endregion
 
@@ -134,7 +136,6 @@
       _tsHelper = new TSHelperTools();
       _channelInfo = new ChannelInfo();
       _pmtPid = -1;
-      _parameters = new ScanParameters();
       _subChannelId = 0;
       _timeshiftFileName = "";
       _recordingFileName = "";
@@ -163,19 +164,17 @@
       _conditionalAccess = ca;
       _mdplugs = mdplugs;
       _filterTIF = tif;
-      _filterTsWriter = tsWriter;
       _teletextDecoder = new DVBTeletext();
       _packetHeader = new TSHelperTools.TSHeader();
       _tsHelper = new TSHelperTools();
       _channelInfo = new ChannelInfo();
       _pmtPid = -1;
       _subChannelIndex = -1;
-      _tsFilterInterface = (ITsFilter)_filterTsWriter;
+      _tsFilterInterface = (ITsFilter)tsWriter;
       _tsFilterInterface.AddChannel(ref _subChannelIndex);
 
       Log.Log.WriteFile("TvDvbChannel ctor new subchIndex:{0}", _subChannelIndex);
 
-      _parameters = new ScanParameters();
       _subChannelId = subChannelId;
       _conditionalAccess.AddSubChannel(_subChannelId, channel);
       _timeshiftFileName = "";
@@ -211,12 +210,9 @@
     public override void OnBeforeTune()
     {
       Log.Log.WriteFile("subch:{0} OnBeforeTune", _subChannelId);
-      if (IsTimeShifting)
+      if (IsTimeShifting && _subChannelIndex >= 0)
       {
-        if (_subChannelIndex >= 0)
-        {
-          _tsFilterInterface.TimeShiftPause(_subChannelIndex, 1);
-        }
+        _tsFilterInterface.TimeShiftPause(_subChannelIndex, 1);
       }
       _startTimeShifting = false;
       _startRecording = false;
@@ -251,7 +247,7 @@
       _pmtVersion = -1;
     }
 
-    private bool WaitForPMT()
+    protected virtual bool WaitForPMT()
     {
       bool foundPMT = false;
       int retryCount = 0;
@@ -418,7 +414,9 @@
       else
       {
         if (_teletextDecoder != null)
+        {
           _teletextDecoder.ClearBuffer();
+        }
 
         _pmtPid = -1;
         _pmtVersion = -1;
@@ -463,6 +461,7 @@
       _startTimeShifting = false;
       _startRecording = false;
       _pmtVersion = -1;
+      _timeshiftFileName = "";
       _recordingFileName = "";
       _channelInfo = new ChannelInfo();
       _currentChannel = null;
@@ -526,7 +525,6 @@
           {
             Log.Log.Error("subch:{0} tswriter StartRecord failed:{1:X}", _subChannelId, hr);
           }
-          _graphState = GraphState.Recording;
         }
       }
     }
@@ -545,7 +543,6 @@
           Log.Log.WriteFile("tvdvbchannel.OnStopRecording subch:{0}-{1} tswriter StopRecording...", _subChannelId,
                             _subChannelIndex);
           _tsFilterInterface.RecordStopRecord(_subChannelIndex);
-          _graphState = _timeshiftFileName != "" ? GraphState.TimeShifting : GraphState.Created;
         }
       }
       else
@@ -604,16 +601,14 @@
     /// <returns></returns>
     protected override void OnStopTimeShifting()
     {
-      if (_timeshiftFileName != "")
+      if (IsTimeShifting)
       {
         Log.Log.WriteFile("subch:{0}-{1} tswriter StopTimeshifting...", _subChannelId, _subChannelIndex);
         if (_tsFilterInterface != null)
         {
           _tsFilterInterface.TimeShiftStop(_subChannelIndex);
         }
-        _graphState = GraphState.Created;
       }
-      _timeshiftFileName = "";
     }
 
     /// <summary>
@@ -829,7 +824,10 @@
         _tsFilterInterface.DeleteChannel(_subChannelIndex);
         _subChannelIndex = -1;
       }
-      _conditionalAccess.FreeSubChannel(_subChannelId);
+      if (_conditionalAccess != null)
+      {
+        _conditionalAccess.FreeSubChannel(_subChannelId);
+      }
     }
 
     #endregion
@@ -895,7 +893,7 @@
         Log.Log.WriteFile("subch:{0}  pid:{1:X} pcr", _subChannelId, info.pcrPid);
         Log.Log.WriteFile("subch:{0}  pid:{1:X} pmt", _subChannelId, info.network_pmt_PID);
 
-        if (info.network_pmt_PID >= 0 && ((DVBBaseChannel)_currentChannel).ServiceId >= 0)
+        if (info.network_pmt_PID >= 0 && info.serviceID >= 0)
         {
           hwPids.Add((ushort)info.network_pmt_PID);
         }
@@ -991,7 +989,7 @@
           Log.Log.WriteFile("Number of HWPIDS that needs to be sent to tuner :{0} ", hwPids.Count);
         }
 
-        if (info.network_pmt_PID >= 0 && ((DVBBaseChannel)_currentChannel).ServiceId >= 0)
+        if (_conditionalAccess != null && info.network_pmt_PID >= 0 && info.serviceID >= 0)
         {
           _conditionalAccess.SendPids(_subChannelId, (DVBBaseChannel)_currentChannel, hwPids);
         }
@@ -1046,7 +1044,7 @@
     /// <summary>
     /// Sets the pids for the timeshifter
     /// </summary>
-    private void SetTimeShiftPids()
+    protected virtual void SetTimeShiftPids()
     {
       //Log.Log.WriteFile("SetTimeShiftPids new DLL");
       if (_channelInfo == null)
@@ -1056,14 +1054,11 @@
       if (_currentChannel == null)
         return;
       //if (_currentAudioStream == null) return;
-      DVBBaseChannel dvbChannel = _currentChannel as DVBBaseChannel;
-      if (dvbChannel == null)
-        return;
 
       try
       {
         _tsFilterInterface.TimeShiftPause(_subChannelIndex, 1);
-        _tsFilterInterface.TimeShiftSetPmtPid(_subChannelIndex, dvbChannel.PmtPid, dvbChannel.ServiceId, _pmtData,
+        _tsFilterInterface.TimeShiftSetPmtPid(_subChannelIndex, _channelInfo.network_pmt_PID, _channelInfo.serviceID, _pmtData,
                                               _pmtLength);
 
         //_linkageScannerEnabled = (layer.GetSetting("linkageScannerEnabled", "no").Value == "yes");
@@ -1080,7 +1075,7 @@
     /// <summary>
     /// Sets the pids for the recorder
     /// </summary>
-    private void SetRecorderPids()
+    protected void SetRecorderPids()
     {
       Log.Log.WriteFile("SetRecorderPids");
       if (_channelInfo == null)
@@ -1091,22 +1086,18 @@
         return;
       if (_currentAudioStream == null)
         return;
-      DVBBaseChannel dvbChannel = _currentChannel as DVBBaseChannel;
-      if (dvbChannel == null)
-        return;
 
-      if (dvbChannel.PmtPid > 0)
+      if (_channelInfo.network_pmt_PID > 0)
       {
-        _tsFilterInterface.RecordSetPmtPid(_subChannelIndex, dvbChannel.PmtPid, dvbChannel.ServiceId, _pmtData,
+        _tsFilterInterface.RecordSetPmtPid(_subChannelIndex, _channelInfo.network_pmt_PID, _channelInfo.serviceID, _pmtData,
                                            _pmtLength);
       }
-      _dateRecordingStarted = DateTime.Now;
     }
 
     /// <summary>
     /// Decodes the PMT and sends the PMT to cam.
     /// </summary>
-    protected bool SendPmtToCam(out bool updatePids, out int waitInterval)
+    protected virtual bool SendPmtToCam(out bool updatePids, out int waitInterval)
     {
       lock (this)
       {
@@ -1168,6 +1159,7 @@
               _channelInfo = new ChannelInfo();
               _channelInfo.DecodePmt(_pmtData);
               _channelInfo.network_pmt_PID = channel.PmtPid;
+              _channelInfo.serviceID = channel.ServiceId;
 
               // update any service scrambled / unscambled changes
               if (_channelInfo.scrambled == channel.FreeToAir)
