///<summary>
    /// Scan NIT channel
    ///</summary>
    ///<param name="channel">Channel</param>
    ///<param name="settings">Scan Parameters</param>
    ///<returns>Found channels</returns>
    public List<IChannel> ScanNIT(IChannel channel, ScanParameters settings)
    {
      try
      {
        _card.IsScanning = true;
        _card.Scan(0, channel);
        _analyzer = GetAnalyzer();
        if (_analyzer == null)
        {
          Log.Log.WriteFile("Scan: no analyzer interface available");
          return new List<IChannel>();
        }
        _analyzer.SetCallBack(null);
        _analyzer.ScanNIT();
        Thread.Sleep(settings.TimeOutTune * 1000);
        ResetSignalUpdate();
        Log.Log.WriteFile("ScanNIT: tuner locked:{0} signal:{1} quality:{2}", _card.IsTunerLocked, _card.SignalLevel,
                          _card.SignalQuality);
        if (_card.IsTunerLocked || _card.SignalLevel > 0 || _card.SignalQuality > 0)
        {
          int count;

          _event = new ManualResetEvent(false);
          _event.WaitOne(16000, true);
          _event.Close();
          List<IChannel> channelsFound = new List<IChannel>();
          _analyzer.GetNITCount(out count);
          for (int i = 0; i < count; ++i)
          {
            int freq, pol, mod, symbolrate, bandwidth, innerfec, rollOff, chType;
            IntPtr ptrName;
            _analyzer.GetNITChannel((short)i, out chType, out freq, out pol, out mod, out symbolrate, out bandwidth,
                                    out innerfec, out rollOff, out ptrName);
            string name = DvbTextConverter.Convert(ptrName, "");
            if (chType == 0)
            {
              DVBSChannel ch = new DVBSChannel();
              ch.Name = name;
              ch.Frequency = freq;
              Log.Log.Debug("{0},{1},{2},{3}", freq, mod, pol, symbolrate);
              switch (mod)
              {
                default:
                case 0:
                  ch.ModulationType = ModulationType.ModNotSet;
                  break;
                  //case 1: ch.ModulationType = ModulationType.ModQpsk; break;
                case 2:
                  ch.ModulationType = ModulationType.Mod8Psk;
                  break;
                case 3:
                  ch.ModulationType = ModulationType.Mod16Qam;
                  break;
              }
              ch.SymbolRate = symbolrate;
              ch.InnerFecRate = (BinaryConvolutionCodeRate)innerfec;
              ch.Polarisation = (Polarisation)pol;
              ch.Rolloff = (RollOff)rollOff;
              channelsFound.Add(ch);
            }
            else if (chType == 1)
            {
              DVBCChannel ch = new DVBCChannel();
              ch.Name = name;
              ch.Frequency = freq;
              ch.ModulationType = (ModulationType)mod;
              ch.SymbolRate = symbolrate;
              channelsFound.Add(ch);
            }
            else if (chType == 2)
            {
              DVBTChannel ch = new DVBTChannel();
              ch.Name = name;
              ch.Frequency = freq;
              ch.BandWidth = bandwidth;
              channelsFound.Add(ch);
            }
          }
          _analyzer.StopNIT();
          return channelsFound;
        }
        else
        {
          Log.Log.WriteFile("Scan: no signal detected");
          return new List<IChannel>();
        }
      }
      finally
      {
        if (_analyzer != null)
        {
          _analyzer.StopNIT();
        }
        _card.IsScanning = false;
      }
    }
    /// <summary>
    /// Scans the specified transponder.
    /// </summary>
    /// <param name="channel">The channel.</param>
    /// <param name="settings">The settings.</param>
    /// <returns></returns>
    public virtual List<IChannel> Scan(IChannel channel, ScanParameters settings)
    {
      try
      {
        bool isDigitalCableScan = false;
        if (_card is TunerPbdaCableCard)
        {
          isDigitalCableScan = true;
        }
        _card.IsScanning = true;
        _card.Scan(0, channel);
        _analyzer = GetAnalyzer();
        if (_analyzer == null)
        {
          Log.Log.WriteFile("Scan: no analyzer interface available");
          return new List<IChannel>();
        }
        ResetSignalUpdate();

        // Note we don't check lock for PBDA CableCARD tuners because
        // they scan using the out of band tuner. OOB lock has already
        // been checked.
        if (_card.IsTunerLocked == false && !isDigitalCableScan)
        {
          Thread.Sleep(settings.TimeOutTune * 1000);
          ResetSignalUpdate();
        }
        Log.Log.WriteFile("Scan: tuner locked:{0} signal:{1} quality:{2}", _card.IsTunerLocked, _card.SignalLevel,
                          _card.SignalQuality);
        if (_card.IsTunerLocked || _card.SignalLevel > 0 || _card.SignalQuality > 0 || isDigitalCableScan)
        {
          try
          {
            _event = new ManualResetEvent(false);
            _analyzer.SetCallBack(this);
            _analyzer.Start(_transportStreamStandard);
            _event.WaitOne(settings.TimeOutSDT * 1000, true);

            int found = 0;
            short channelCount;
            _analyzer.GetCount(out channelCount);
            List<IChannel> channelsFound = new List<IChannel>();

            for (int i = 0; i < channelCount; ++i)
            {
              int networkId;
              int transportId;
              int serviceId;
              int majorChannel;
              int minorChannel;
              int frequency;
              short freeCAMode;
              short serviceType;
              short modulation;
              IntPtr providerName;
              IntPtr serviceName;
              int pmtPid;
              short hasVideo;
              short hasAudio;
              short hasCaDescriptor;
              int lcn;
              _analyzer.GetChannel((short)i,
                                   out networkId, out transportId, out serviceId, out majorChannel, out minorChannel,
                                   out frequency, out lcn, out freeCAMode, out serviceType, out modulation,
                                   out providerName, out serviceName,
                                   out pmtPid, out hasVideo, out hasAudio, out hasCaDescriptor);

              string name = DvbTextConverter.Convert(serviceName, "");
              Log.Log.Write("{0}) 0x{1:X} 0x{2:X} 0x{3:X} 0x{4:X} {5} type:{6:X}", i, networkId, transportId, serviceId,
                            pmtPid, name, serviceType);

              found++;
              ChannelInfo info = new ChannelInfo();
              info.networkID = networkId;
              info.transportStreamID = transportId;
              info.serviceID = serviceId;
              info.majorChannel = majorChannel;
              info.minorChannel = minorChannel;
              info.freq = frequency;
              info.LCN = lcn;
              info.serviceType = serviceType;
              info.modulation = modulation;
              info.service_provider_name = DvbTextConverter.Convert(providerName, "");
              info.service_name = DvbTextConverter.Convert(serviceName, "");
              info.scrambled = (freeCAMode != 0 || hasCaDescriptor != 0);
              info.network_pmt_PID = pmtPid;

              if (IsValidChannel(info, hasAudio, hasVideo))
              {
                if (info.service_name.Length == 0)
                {
                  SetNameForUnknownChannel(channel, info);
                }
                IChannel result = CreateNewChannel(channel, info);
                if (result != null)
                {
                  channelsFound.Add(result);
                }
              }
              else
              {
                Log.Log.Write(
                  "Found Unknown: {0} {1} type:{2} onid:{3:X} tsid:{4:X} sid:{5:X} pmt:{6:X} hasVideo:{7} hasAudio:{8}",
                  info.service_provider_name, info.service_name, info.serviceType, info.networkID,
                  info.transportStreamID, info.serviceID, info.network_pmt_PID, hasVideo, hasAudio);
              }
            }

            Log.Log.Write("Scan Got {0} from {1} channels", found, channelCount);
            return channelsFound;
          }
          finally
          {
            if (_analyzer != null)
            {
              _analyzer.SetCallBack(null);
              _analyzer.Stop();
            }
            _event.Close();
          }
        }
        else
        {
          Log.Log.WriteFile("Scan: no signal detected");
          return new List<IChannel>();
        }
      }
      finally
      {
        _card.IsScanning = false;
      }
    }
    /// <summary>
    /// destroys the graph and cleans up any resources
    /// </summary>
    protected void Decompose()
    {
      if (_graphBuilder == null || !CheckThreadId())
        return;

      Log.Log.WriteFile("dvb:Decompose");
      if (_epgGrabbing)
      {
        if (_epgGrabberCallback != null && _epgGrabbing)
        {
          Log.Log.Epg("dvb:cancel epg->decompose");
          _epgGrabberCallback.OnEpgCancelled();
        }
        _epgGrabbing = false;
      }

      FreeAllSubChannels();
      Log.Log.WriteFile("  stop");
      // Decompose the graph

      int counter = 0, hr = 0;
      FilterState state = FilterState.Running;
      hr = ((IMediaControl)_graphBuilder).Stop();
      while (state != FilterState.Stopped)
      {
        System.Threading.Thread.Sleep(100);
        hr = ((IMediaControl)_graphBuilder).GetState(10, out state);
        counter++;
        if (counter >= 30)
        {
          if (state != FilterState.Stopped)
            Log.Log.Error("dvb:graph still running");
          break;
        }
      }

      //In case MDPlugs exists then close and release them
      if (_mdplugs != null)
      {
        Log.Log.Info("  Closing MDAPI Plugins");
        _mdplugs.Close();
        _mdplugs = null;
      }
      if (_conditionalAccess != null)
      {
        Log.Log.Info("  Disposing ConditionalAccess");
        _conditionalAccess.Dispose();
        _conditionalAccess = null;
      }

      Log.Log.WriteFile("  free...");
      _interfaceChannelScan = null;
      _interfaceEpgGrabber = null;
      _previousChannel = null;
      if (_filterMpeg2DemuxTif != null)
      {
        Release.ComObject("_filterMpeg2DemuxTif filter", _filterMpeg2DemuxTif);
        _filterMpeg2DemuxTif = null;
      }
      if (_filterNetworkProvider != null)
      {
        Release.ComObject("_filterNetworkProvider filter", _filterNetworkProvider);
        _filterNetworkProvider = null;
      }
      if (_infTeeMain != null)
      {
        Release.ComObject("main inftee filter", _infTeeMain);
        _infTeeMain = null;
      }
      if (_infTeeSecond != null)
      {
        Release.ComObject("second inftee filter", _infTeeSecond);
        _infTeeSecond = null;
      }
      if (_filterTuner != null)
      {
        while (Release.ComObject(_filterTuner) > 0)
          ;
        _filterTuner = null;
      }
      if (_filterCapture != null)
      {
        while (Release.ComObject(_filterCapture) > 0)
          ;
        _filterCapture = null;
      }
      if (_filterWinTvUsb != null)
      {
        Log.Log.Info("  Stopping WinTVCI module");
        winTvCiHandler.Shutdown();
        while (Release.ComObject(_filterWinTvUsb) > 0)
          ;
        _filterWinTvUsb = null;
      }
      if (_filterTIF != null)
      {
        Release.ComObject("TIF filter", _filterTIF);
        _filterTIF = null;
      }
      //if (_filterSectionsAndTables != null)
      //{
      //  Release.ComObject("secions&tables filter", _filterSectionsAndTables); _filterSectionsAndTables = null;
      //}
      Log.Log.WriteFile("  free pins...");
      if (_filterTsWriter as IBaseFilter != null)
      {
        Release.ComObject("TSWriter filter", _filterTsWriter);
        _filterTsWriter = null;
      }
      else
      {
        Log.Log.Debug("!!! Error releasing TSWriter filter (_filterTsWriter as IBaseFilter was null!)");
        _filterTsWriter = null;
      }
      Log.Log.WriteFile("  free graph...");
      if (_rotEntry != null)
      {
        _rotEntry.Dispose();
        _rotEntry = null;
      }
      if (_capBuilder != null)
      {
        Release.ComObject("capture builder", _capBuilder);
        _capBuilder = null;
      }
      if (_graphBuilder != null)
      {
        FilterGraphTools.RemoveAllFilters(_graphBuilder);
        Release.ComObject("graph builder", _graphBuilder);
        _graphBuilder = null;
      }
      Log.Log.WriteFile("  free devices...");
      if (_deviceWinTvUsb != null)
      {
        DevicesInUse.Instance.Remove(_deviceWinTvUsb);
        _deviceWinTvUsb = null;
      }
      if (_tunerDevice != null)
      {
        DevicesInUse.Instance.Remove(_tunerDevice);
        _tunerDevice = null;
      }
      if (_captureDevice != null)
      {
        DevicesInUse.Instance.Remove(_captureDevice);
        _captureDevice = null;
      }
      if (_tunerStatistics != null)
      {
        for (int i = 0; i < _tunerStatistics.Count; i++)
        {
          IBDA_SignalStatistics stat = _tunerStatistics[i];
          while (Release.ComObject(stat) > 0)
            ;
        }
        _tunerStatistics.Clear();
      }
      Log.Log.WriteFile("  decompose done...");
      _graphState = GraphState.Idle;
    }
 /// <summary>
 /// Gets the video audio pins.
 /// </summary>
 protected void AddTsWriterFilterToGraph()
 {
   if (_filterTsWriter == null)
   {
     Log.Log.WriteFile("dvb:  Add Mediaportal TsWriter filter");
     _filterTsWriter = (IBaseFilter)new MpTsAnalyzer();
     int hr = _graphBuilder.AddFilter(_filterTsWriter, "MediaPortal Ts Analyzer");
     if (hr != 0)
     {
       Log.Log.Error("dvb:  Add main Ts Analyzer returns:0x{0:X}", hr);
       throw new TvException("Unable to add Ts Analyzer filter");
     }
     _interfaceChannelScan = (ITsChannelScan)_filterTsWriter;
     _interfaceEpgGrabber = (ITsEpgScanner)_filterTsWriter;
     _interfaceChannelLinkageScanner = (ITsChannelLinkageScanner)_filterTsWriter;
   }
 }
        ///<summary>
        /// Scan NIT channel
        ///</summary>
        ///<param name="channel">Channel</param>
        ///<param name="settings">Scan Parameters</param>
        ///<returns>Found channels</returns>
        public List <IChannel> ScanNIT(IChannel channel, ScanParameters settings)
        {
            try
            {
                _card.IsScanning = true;
                _card.Scan(0, channel);
                _analyzer = GetAnalyzer();
                if (_analyzer == null)
                {
                    Log.Log.WriteFile("Scan: no analyzer interface available");
                    return(new List <IChannel>());
                }
                _analyzer.SetCallBack(null);
                _analyzer.ScanNIT();
                Thread.Sleep(settings.TimeOutTune * 1000);
                ResetSignalUpdate();
                Log.Log.WriteFile("ScanNIT: tuner locked:{0} signal:{1} quality:{2}", _card.IsTunerLocked, _card.SignalLevel,
                                  _card.SignalQuality);
                if (_card.IsTunerLocked || _card.SignalLevel > 0 || _card.SignalQuality > 0)
                {
                    int count;

                    _event = new ManualResetEvent(false);
                    _event.WaitOne(16000, true);
                    _event.Close();
                    List <IChannel> channelsFound = new List <IChannel>();
                    _analyzer.GetNITCount(out count);
                    for (int i = 0; i < count; ++i)
                    {
                        int    freq, pol, mod, symbolrate, bandwidth, innerfec, rollOff, chType;
                        IntPtr ptrName;
                        _analyzer.GetNITChannel((short)i, out chType, out freq, out pol, out mod, out symbolrate, out bandwidth,
                                                out innerfec, out rollOff, out ptrName);
                        string name = DvbTextConverter.Convert(ptrName, "");
                        if (chType == 0)
                        {
                            DVBSChannel ch = new DVBSChannel();
                            ch.Name      = name;
                            ch.Frequency = freq;
                            Log.Log.Debug("{0},{1},{2},{3}", freq, mod, pol, symbolrate);
                            switch (mod)
                            {
                            default:
                            case 0:
                                ch.ModulationType = ModulationType.ModNotSet;
                                break;

                            //case 1: ch.ModulationType = ModulationType.ModQpsk; break;
                            case 2:
                                ch.ModulationType = ModulationType.Mod8Psk;
                                break;

                            case 3:
                                ch.ModulationType = ModulationType.Mod16Qam;
                                break;
                            }
                            ch.SymbolRate   = symbolrate;
                            ch.InnerFecRate = (BinaryConvolutionCodeRate)innerfec;
                            ch.Polarisation = (Polarisation)pol;
                            ch.Rolloff      = (RollOff)rollOff;
                            channelsFound.Add(ch);
                        }
                        else if (chType == 1)
                        {
                            DVBCChannel ch = new DVBCChannel();
                            ch.Name           = name;
                            ch.Frequency      = freq;
                            ch.ModulationType = (ModulationType)mod;
                            ch.SymbolRate     = symbolrate;
                            channelsFound.Add(ch);
                        }
                        else if (chType == 2)
                        {
                            DVBTChannel ch = new DVBTChannel();
                            ch.Name      = name;
                            ch.Frequency = freq;
                            ch.BandWidth = bandwidth;
                            channelsFound.Add(ch);
                        }
                    }
                    _analyzer.StopNIT();
                    return(channelsFound);
                }
                else
                {
                    Log.Log.WriteFile("Scan: no signal detected");
                    return(new List <IChannel>());
                }
            }
            finally
            {
                if (_analyzer != null)
                {
                    _analyzer.StopNIT();
                }
                _card.IsScanning = false;
            }
        }
        /// <summary>
        /// Scans the specified transponder.
        /// </summary>
        /// <param name="channel">The channel.</param>
        /// <param name="settings">The settings.</param>
        /// <returns></returns>
        public List <IChannel> Scan(IChannel channel, ScanParameters settings)
        {
            try
            {
                _card.IsScanning = true;
                _card.Scan(0, channel);
                _analyzer = GetAnalyzer();
                if (_analyzer == null)
                {
                    Log.Log.WriteFile("Scan: no analyzer interface available");
                    return(new List <IChannel>());
                }
                ResetSignalUpdate();
                if (_card.IsTunerLocked == false)
                {
                    Thread.Sleep(settings.TimeOutTune * 1000);
                    ResetSignalUpdate();
                }
                Log.Log.WriteFile("Scan: tuner locked:{0} signal:{1} quality:{2}", _card.IsTunerLocked, _card.SignalLevel,
                                  _card.SignalQuality);
                if (_card.IsTunerLocked || _card.SignalLevel > 0 || _card.SignalQuality > 0)
                {
                    try
                    {
                        _event = new ManualResetEvent(false);
                        _analyzer.SetCallBack(this);
                        _analyzer.Start(_enableWaitForVCT);
                        _event.WaitOne(settings.TimeOutSDT * 1000, true);

                        int   found = 0;
                        short channelCount;
                        _analyzer.GetCount(out channelCount);
                        List <IChannel> channelsFound = new List <IChannel>();

                        for (int i = 0; i < channelCount; ++i)
                        {
                            int    networkId;
                            int    transportId;
                            int    serviceId;
                            short  majorChannel;
                            short  minorChannel;
                            short  frequency;
                            short  freeCAMode;
                            short  serviceType;
                            short  modulation;
                            IntPtr providerName;
                            IntPtr serviceName;
                            short  pmtPid;
                            short  hasVideo;
                            short  hasAudio;
                            short  hasCaDescriptor;
                            short  lcn;
                            _analyzer.GetChannel((short)i,
                                                 out networkId, out transportId, out serviceId, out majorChannel, out minorChannel,
                                                 out frequency, out lcn, out freeCAMode, out serviceType, out modulation,
                                                 out providerName, out serviceName,
                                                 out pmtPid, out hasVideo, out hasAudio, out hasCaDescriptor);

                            string name = DvbTextConverter.Convert(serviceName, "");
                            Log.Log.Write("{0}) 0x{1:X} 0x{2:X} 0x{3:X} 0x{4:X} {5} type:{6:X}", i, networkId, transportId, serviceId,
                                          pmtPid, name, serviceType);

                            found++;
                            ChannelInfo info = new ChannelInfo();
                            info.networkID         = networkId;
                            info.transportStreamID = transportId;
                            info.serviceID         = serviceId;
                            info.majorChannel      = majorChannel;
                            info.minorChannel      = minorChannel;
                            info.freq                  = frequency;
                            info.LCN                   = lcn;
                            info.serviceType           = serviceType;
                            info.modulation            = modulation;
                            info.service_provider_name = DvbTextConverter.Convert(providerName, "");
                            info.service_name          = DvbTextConverter.Convert(serviceName, "");
                            info.scrambled             = (freeCAMode != 0 || hasCaDescriptor != 0);
                            info.network_pmt_PID       = pmtPid;

                            if (IsValidChannel(info, hasAudio, hasVideo))
                            {
                                if (info.service_name.Length == 0)
                                {
                                    SetNameForUnknownChannel(channel, info);
                                }
                                IChannel result = CreateNewChannel(channel, info);
                                if (result != null)
                                {
                                    channelsFound.Add(result);
                                }
                            }
                            else
                            {
                                Log.Log.Write(
                                    "Found Unknown: {0} {1} type:{2} onid:{3:X} tsid:{4:X} sid:{5:X} pmt:{6:X} hasVideo:{7} hasAudio:{8}",
                                    info.service_provider_name, info.service_name, info.serviceType, info.networkID,
                                    info.transportStreamID, info.serviceID, info.network_pmt_PID, hasVideo, hasAudio);
                            }
                        }

                        Log.Log.Write("Scan Got {0} from {1} channels", found, channelCount);
                        return(channelsFound);
                    }
                    finally
                    {
                        if (_analyzer != null)
                        {
                            _analyzer.SetCallBack(null);
                            _analyzer.Stop();
                        }
                        _event.Close();
                    }
                }
                else
                {
                    Log.Log.WriteFile("Scan: no signal detected");
                    return(new List <IChannel>());
                }
            }
            finally
            {
                _card.IsScanning = false;
            }
        }