Ejemplo n.º 1
0
 /// <summary>
 /// Creates the Graph instance which represents an analog graph
 /// </summary>
 /// <param name="xmlNode">The graph xml node</param>
 /// <returns>Graph instance</returns>
 public static Graph CreateInstance(XmlNode xmlNode)
 {
   Graph graph = new Graph();
   XmlNode tunerNode = null;
   XmlNode tvAudioNode = null;
   XmlNode crossbarNode = null;
   XmlNode captureNode = null;
   XmlNode teletextNode = null;
   if (xmlNode != null)
   {
     tunerNode = xmlNode.SelectSingleNode("tuner");
     tvAudioNode = xmlNode.SelectSingleNode("tvAudio");
     crossbarNode = xmlNode.SelectSingleNode("crossbar");
     captureNode = xmlNode.SelectSingleNode("capture");
     teletextNode = xmlNode.SelectSingleNode("teletext");
   }
   graph.Tuner = Tuner.CreateInstance(tunerNode);
   graph.TvAudio = TvAudio.CreateInstance(tvAudioNode);
   graph.Crossbar = Crossbar.CreateInstance(crossbarNode);
   graph.Capture = Capture.CreateInstance(captureNode);
   graph.Teletext = Teletext.CreateInstance(teletextNode);
   return graph;
 }
Ejemplo n.º 2
0
 /// <summary>
 /// Detects the capabilities of the tv audio device
 /// </summary>
 private void CheckCapabilities(Graph graph)
 {
   TVAudioMode availableAudioModes;
   _tvAudioTunerInterface.GetHardwareSupportedTVAudioModes(out availableAudioModes);
   graph.TvAudio.AudioModes = availableAudioModes;
   if ((availableAudioModes & (TVAudioMode.Stereo)) != 0)
   {
     AnalogAudioStream stream = new AnalogAudioStream();
     stream.AudioMode = TVAudioMode.Stereo;
     stream.Language = "Stereo";
     streams.Add(stream);
   }
   if ((availableAudioModes & (TVAudioMode.Mono)) != 0)
   {
     AnalogAudioStream stream = new AnalogAudioStream();
     stream.AudioMode = TVAudioMode.Mono;
     stream.Language = "Mono";
     streams.Add(stream);
   }
   if ((availableAudioModes & (TVAudioMode.LangA)) != 0)
   {
     AnalogAudioStream stream = new AnalogAudioStream();
     stream.AudioMode = TVAudioMode.LangA;
     stream.Language = "LangA";
     streams.Add(stream);
   }
   if ((availableAudioModes & (TVAudioMode.LangB)) != 0)
   {
     AnalogAudioStream stream = new AnalogAudioStream();
     stream.AudioMode = TVAudioMode.LangB;
     stream.Language = "LangB";
     streams.Add(stream);
   }
   if ((availableAudioModes & (TVAudioMode.LangC)) != 0)
   {
     AnalogAudioStream stream = new AnalogAudioStream();
     stream.AudioMode = TVAudioMode.LangC;
     stream.Language = "LangC";
     streams.Add(stream);
   }
 }
Ejemplo n.º 3
0
 /// <summary>
 /// Creates the filter by trying to detect it
 /// </summary>
 /// <param name="crossbar">The crossbar componen</param>
 /// <param name="tuner">The tuner component</param>
 /// <param name="graph">The stored graph</param>
 /// <param name="graphBuilder">The graphBuilder</param>
 /// <returns>true, if the graph building was successful</returns>
 private bool CreateAutomaticFilterInstance(Graph graph, Tuner tuner, Crossbar crossbar, IFilterGraph2 graphBuilder)
 {
   //get all tv audio tuner devices on this system
   DsDevice[] devices = null;
   try
   {
     devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSTVAudio);
     devices = DeviceSorter.Sort(devices, tuner.TunerName, crossbar.CrossBarName);
   }
   catch (Exception)
   {
     Log.Log.WriteFile("analog: AddTvAudioFilter no tv audio devices found - Trying TvTuner filter");
   }
   if (devices != null && devices.Length > 0)
   {
     // try each tv audio tuner
     for (int i = 0; i < devices.Length; i++)
     {
       IBaseFilter tmp;
       Log.Log.WriteFile("analog: AddTvAudioFilter try:{0} {1}", devices[i].Name, i);
       //if tv audio tuner is currently in use we can skip it
       if (DevicesInUse.Instance.IsUsed(devices[i]))
         continue;
       int hr;
       try
       {
         //add tv audio tuner to graph
         hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
       }
       catch (Exception)
       {
         Log.Log.WriteFile("analog: cannot add filter to graph");
         continue;
       }
       if (hr != 0)
       {
         //failed to add tv audio tuner to graph, continue with the next one
         if (tmp != null)
         {
           graphBuilder.RemoveFilter(tmp);
           Release.ComObject("tvAudioFilter filter", tmp);
         }
         continue;
       }
       // try connecting the tv tuner-> tv audio tuner
       if (FilterGraphTools.ConnectPin(graphBuilder, tuner.AudioPin, tmp, 0))
       {
         // Got it !
         // Connect tv audio tuner to the crossbar
         IPin pin = DsFindPin.ByDirection(tmp, PinDirection.Output, 0);
         hr = graphBuilder.Connect(pin, crossbar.AudioTunerIn);
         if (hr < 0)
         {
           //failed
           graphBuilder.RemoveFilter(tmp);
           Release.ComObject("audiotuner pinin", pin);
           Release.ComObject("audiotuner filter", tmp);
         }
         else
         {
           //succeeded. we're done
           Log.Log.WriteFile("analog: AddTvAudioFilter succeeded:{0}", devices[i].Name);
           Release.ComObject("audiotuner pinin", pin);
           _filterTvAudioTuner = tmp;
           _audioDevice = devices[i];
           DevicesInUse.Instance.Add(_audioDevice);
           _tvAudioTunerInterface = tuner.Filter as IAMTVAudio;
           break;
         }
       }
       else
       {
         // cannot connect tv tuner-> tv audio tuner, try next one...
         graphBuilder.RemoveFilter(tmp);
         Release.ComObject("audiotuner filter", tmp);
       }
     }
   }
   if (_filterTvAudioTuner == null)
   {
     Log.Log.WriteFile("analog: AddTvAudioFilter no tv audio devices found - Trying TvTuner filter");
     int hr = graphBuilder.Connect(tuner.AudioPin, crossbar.AudioTunerIn);
     if (hr != 0)
     {
       Log.Log.Error("analog: unable to add TvAudioTuner to graph - even TvTuner as TvAudio fails");
       mode = TvAudioVariant.Unavailable;
     }
     else
     {
       Log.Log.WriteFile("analog: AddTvAudioFilter connected TvTuner with Crossbar directly succeeded!");
       mode = TvAudioVariant.TvTunerConnection;
       _tvAudioTunerInterface = tuner.Filter as IAMTVAudio;
       if (_tvAudioTunerInterface != null)
       {
         Log.Log.WriteFile("analog: AddTvAudioFilter succeeded - TvTuner is also TvAudio");
         _filterTvAudioTuner = tuner.Filter;
         mode = TvAudioVariant.TvTuner;
       }
     }
     graph.TvAudio.Mode = mode;
   }
   else
   {
     mode = TvAudioVariant.Normal;
     graph.TvAudio.Name = _audioDevice.Name;
   }
   if (mode != TvAudioVariant.Unavailable && mode != TvAudioVariant.TvTunerConnection &&
       _tvAudioTunerInterface != null)
   {
     CheckCapabilities(graph);
   }
   return true;
 }
Ejemplo n.º 4
0
    /// <summary>
    /// Adds the tv audio tuner to the graph and connects it to the crossbar.
    /// At the end of this method the graph looks like:
    /// [          ] ------------------------->[           ]
    /// [ tvtuner  ]                           [ crossbar  ]
    /// [          ]----[            ]-------->[           ]
    ///                 [ tvaudio    ]
    ///                 [   tuner    ]
    /// </summary>
    /// <param name="crossbar">The crossbar componen</param>
    /// <param name="tuner">The tuner component</param>
    /// <param name="graph">The stored graph</param>
    /// <param name="graphBuilder">The graphBuilder</param>
    /// <returns>true, if the graph building was successful</returns>
    public bool CreateFilterInstance(Graph graph, IFilterGraph2 graphBuilder, Tuner tuner, Crossbar crossbar)
    {
      streams = new List<IAudioStream>();
      if (!string.IsNullOrEmpty(graph.TvAudio.Name) && graph.TvAudio.Mode != TvAudioVariant.Unavailable)
      {
        Log.Log.WriteFile("analog: Using TvAudio configuration from stored graph");

        if (CreateConfigurationBasedFilterInstance(graph, tuner, crossbar, graphBuilder))
        {
          Log.Log.WriteFile("analog: Using TvAudio configuration from stored graph succeeded");
          return true;
        }
      }
      if (tuner.AudioPin == null)
      {
        Log.Log.WriteFile("analog: AddTvAudioFilter no tv audio device needed!");
        mode = TvAudioVariant.Unavailable;
        return true;
      }
      Log.Log.WriteFile("analog: No stored graph for TvAudio component - Trying to detect");
      return CreateAutomaticFilterInstance(graph, tuner, crossbar, graphBuilder);
    }
Ejemplo n.º 5
0
    /// <summary>
    /// Creates the filter by trying to detect it
    /// </summary>
    /// <param name="tuner">The tuner component</param>
    /// <param name="graph">The stored graph</param>
    /// <param name="graphBuilder">The graphBuilder</param>
    /// <returns>true, if the graph building was successful</returns>
    private bool CreateAutomaticFilterInstance(Graph graph, IFilterGraph2 graphBuilder, Tuner tuner)
    {
      _audioTunerIn = null;
      DsDevice[] devices;
      //get list of all crossbar devices installed on this system
      try
      {
        devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSCrossbar);
        devices = DeviceSorter.Sort(devices, graph.Tuner.Name);
      }
      catch (Exception)
      {
        Log.Log.WriteFile("analog: AddCrossBarFilter no crossbar devices found");
        return false;
      }
      if (devices == null || devices.Length == 0)
      {
        Log.Log.WriteFile("analog: AddCrossBarFilter no crossbar devices found");
        return false;
      }
      //try each crossbar
      for (int i = 0; i < devices.Length; i++)
      {
        IBaseFilter tmp;
        Log.Log.WriteFile("analog: AddCrossBarFilter try:{0} {1}", devices[i].Name, i);
        //if crossbar is already in use then we can skip it
        if (DevicesInUse.Instance.IsUsed(devices[i]))
          continue;
        int hr;
        try
        {
          //add the crossbar to the graph
          hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
        }
        catch (Exception)
        {
          Log.Log.WriteFile("analog: cannot add filter to graph");
          continue;
        }
        if (hr != 0)
        {
          //failed. try next crossbar
          if (tmp != null)
          {
            graphBuilder.RemoveFilter(tmp);
            Release.ComObject("CrossBarFilter", tmp);
          }
          continue;
        }
        _crossBarFilter = (IAMCrossbar)tmp;
        CheckCapabilities();
        if (_videoOutPinIndex == -1)
        {
          Log.Log.WriteFile("analog: AddCrossbarFilter no video output found");
          graphBuilder.RemoveFilter(tmp);
          _crossBarFilter = null;
          Release.ComObject("CrossBarFilter", tmp);
          continue;
        }

        // Check that the crossbar has a tuner video input pin.
        IPin pinIn = null;
        if (_videoPinMap.ContainsKey(AnalogChannel.VideoInputType.Tuner))
        {
          pinIn = DsFindPin.ByDirection(tmp, PinDirection.Input, _videoPinMap[AnalogChannel.VideoInputType.Tuner]);
        }
        if (pinIn == null)
        {
          // no pin found, continue with next crossbar
          Log.Log.WriteFile("analog: AddCrossBarFilter no video tuner input pin detected");
          if (tmp != null)
          {
            graphBuilder.RemoveFilter(tmp);
            _crossBarFilter = null;
            Release.ComObject("CrossBarFilter", tmp);
          }
          continue;
        }
        //connect tv tuner->crossbar
        int tempVideoPinIndex;
        if (FilterGraphTools.ConnectFilter(graphBuilder, tuner.Filter, pinIn, out tempVideoPinIndex))
        {
          // Got it, we're done
          _filterCrossBar = tmp;
          _crossBarDevice = devices[i];
          DevicesInUse.Instance.Add(_crossBarDevice);
          if (_audioTunerIn == null)
          {
            _audioTunerIn = DsFindPin.ByDirection(_filterCrossBar, PinDirection.Input,
                                                  _audioPinMap[AnalogChannel.AudioInputType.Tuner]);
          }
          Release.ComObject("crossbar videotuner pin", pinIn);
          _videoOut = DsFindPin.ByDirection(_filterCrossBar, PinDirection.Output, _videoOutPinIndex);
          if (_audioOutPinIndex != -1)
          {
            _audioOut = DsFindPin.ByDirection(_filterCrossBar, PinDirection.Output, _audioOutPinIndex);
          }
          Log.Log.WriteFile("analog: AddCrossBarFilter succeeded");
          graph.Crossbar.AudioOut = _audioOutPinIndex;
          graph.Crossbar.AudioPinMap = _audioPinMap;
          graph.Crossbar.Name = _crossBarDevice.Name;
          graph.Crossbar.VideoOut = _videoOutPinIndex;
          graph.Crossbar.VideoPinMap = _videoPinMap;
          graph.Crossbar.VideoPinRelatedAudioMap = _videoPinRelatedAudioMap;
          graph.Tuner.VideoPin = tempVideoPinIndex;
          break;
        }
        // cannot connect tv tuner to crossbar, try next crossbar device
        graphBuilder.RemoveFilter(tmp);
        Release.ComObject("crossbar videotuner pin", pinIn);
        Release.ComObject("crossbar filter", tmp);
      }
      return _filterCrossBar != null;
    }
Ejemplo n.º 6
0
 /// <summary>
 /// Creates the filter based on the configuration file
 /// </summary>
 /// <param name="tuner">The tuner component</param>
 /// <param name="graph">The stored graph</param>
 /// <param name="graphBuilder">The graphBuilder</param>
 /// <returns>true, if the graph building was successful</returns>
 private bool CreateConfigurationBasedFilterInstance(Graph graph, IFilterGraph2 graphBuilder, Tuner tuner)
 {
   string deviceName = graph.Crossbar.Name;
   _audioTunerIn = null;
   DsDevice[] devices;
   //get list of all crossbar devices installed on this system
   try
   {
     devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSCrossbar);
     devices = DeviceSorter.Sort(devices, graph.Tuner.Name);
   }
   catch (Exception)
   {
     Log.Log.WriteFile("analog: AddCrossBarFilter no crossbar devices found");
     return false;
   }
   if (devices == null || devices.Length == 0)
   {
     Log.Log.WriteFile("analog: AddCrossBarFilter no crossbar devices found");
     return false;
   }
   //try each crossbar
   for (int i = 0; i < devices.Length; i++)
   {
     IBaseFilter tmp;
     //if crossbar is already in use then we can skip it
     if (DevicesInUse.Instance.IsUsed(devices[i]))
       continue;
     if (!deviceName.Equals(devices[i].Name))
       continue;
     Log.Log.WriteFile("analog: AddCrossBarFilter use:{0} {1}", devices[i].Name, i);
     int hr;
     try
     {
       //add the crossbar to the graph
       hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
     }
     catch (Exception)
     {
       Log.Log.WriteFile("analog: cannot add filter to graph");
       continue;
     }
     if (hr != 0)
     {
       //failed. try next crossbar
       if (tmp != null)
       {
         graphBuilder.RemoveFilter(tmp);
         Release.ComObject("CrossBarFilter", tmp);
       }
       continue;
     }
     _crossBarFilter = (IAMCrossbar)tmp;
     _videoPinMap = graph.Crossbar.VideoPinMap;
     _audioPinMap = graph.Crossbar.AudioPinMap;
     _videoPinRelatedAudioMap = graph.Crossbar.VideoPinRelatedAudioMap;
     _videoOutPinIndex = graph.Crossbar.VideoOut;
     _audioOutPinIndex = graph.Crossbar.AudioOut;
     if (_videoOutPinIndex == -1)
     {
       Log.Log.WriteFile("analog: AddCrossbarFilter no video output found");
       graphBuilder.RemoveFilter(tmp);
       _crossBarFilter = null;
       Release.ComObject("CrossBarFilter", tmp);
       continue;
     }
     //connect tv tuner->crossbar
     IPin tunerOut = DsFindPin.ByDirection(tuner.Filter, PinDirection.Output,
                                           graph.Tuner.VideoPin);
     if (tunerOut != null && _videoPinMap.ContainsKey(AnalogChannel.VideoInputType.Tuner) &&
         FilterGraphTools.ConnectPin(graphBuilder, tunerOut, tmp, _videoPinMap[AnalogChannel.VideoInputType.Tuner]))
     {
       // Got it, we're done
       _filterCrossBar = tmp;
       _crossBarDevice = devices[i];
       DevicesInUse.Instance.Add(_crossBarDevice);
       if (_audioTunerIn == null)
       {
         _audioTunerIn = DsFindPin.ByDirection(_filterCrossBar, PinDirection.Input,
                                               _audioPinMap[AnalogChannel.AudioInputType.Tuner]);
       }
       Release.ComObject("tuner video out", tunerOut);
       _videoOut = DsFindPin.ByDirection(_filterCrossBar, PinDirection.Output, _videoOutPinIndex);
       if (_audioOutPinIndex != -1)
       {
         _audioOut = DsFindPin.ByDirection(_filterCrossBar, PinDirection.Output, _audioOutPinIndex);
       }
       Log.Log.WriteFile("analog: AddCrossBarFilter succeeded");
       break;
     }
     // cannot connect tv tuner to crossbar, try next crossbar device
     if (tmp != null)
     {
       graphBuilder.RemoveFilter(tmp);
       Release.ComObject("crossbarFilter filter", tmp);
     }
     if (tunerOut != null)
     {
       Release.ComObject("tuner video out", tunerOut);
     }
   }
   return _filterCrossBar != null;
 }
Ejemplo n.º 7
0
 /// <summary>
 /// Adds the cross bar filter to the graph and connects the tv tuner to the crossbar.
 /// at the end of this method the graph looks like:
 /// [tv tuner]----->[crossbar]
 /// </summary>
 /// <param name="tuner">The tuner component</param>
 /// <param name="graph">The stored graph</param>
 /// <param name="graphBuilder">The graphBuilder</param>
 /// <returns>true, if the graph building was successful</returns>
 public bool CreateFilterInstance(Graph graph, IFilterGraph2 graphBuilder, Tuner tuner)
 {
   if (!string.IsNullOrEmpty(graph.Crossbar.Name))
   {
     Log.Log.WriteFile("analog: Using Crossbar configuration from stored graph");
     if (CreateConfigurationBasedFilterInstance(graph, graphBuilder, tuner))
     {
       Log.Log.WriteFile("analog: Using Crossbar configuration from stored graph succeeded");
       return true;
     }
   }
   Log.Log.WriteFile("analog: No stored or invalid graph for Crossbar component - Trying to detect");
   return CreateAutomaticFilterInstance(graph, graphBuilder, tuner);
 }
Ejemplo n.º 8
0
    /// <summary>
    /// Checks the capabilities of the tuner device
    /// </summary>
    /// <returns>true, if the checks were successful</returns>
    private bool CheckCapabilities(Graph graph)
    {
      if (_tuner == null)
      {
        Log.Log.WriteFile("");
        return false;
      }
      UpdateMinMaxChannel();

      AMTunerModeType tunerModes;
      _tuner.GetAvailableModes(out tunerModes);
      _supportsFMRadio = (AMTunerModeType.FMRadio & tunerModes) != 0;
      _supportsAMRadio = (AMTunerModeType.AMRadio & tunerModes) != 0;
      if (_supportsFMRadio && !_supportsAMRadio)
      {
        graph.Tuner.RadioMode = RadioMode.FM;
      }
      if (!_supportsFMRadio && _supportsAMRadio)
      {
        graph.Tuner.RadioMode = RadioMode.AM;
      }
      if (_supportsFMRadio && _supportsAMRadio)
      {
        graph.Tuner.RadioMode = RadioMode.FM | RadioMode.AM;
      }

      return true;
    }
Ejemplo n.º 9
0
 /// <summary>
 /// Creates the tuner filter instance
 /// </summary>
 /// <param name="graph">The stored graph</param>
 /// <param name="graphBuilder">The graphbuilder</param>
 /// <returns>true, if the graph building was successful</returns>
 public bool CreateFilterInstance(Graph graph, IFilterGraph2 graphBuilder)
 {
   Log.Log.WriteFile("analog: AddTvTunerFilter {0}", _tunerDevice.Name);
   if (DevicesInUse.Instance.IsUsed(_tunerDevice))
     return false;
   IBaseFilter tmp;
   int hr;
   try
   {
     hr = graphBuilder.AddSourceFilterForMoniker(_tunerDevice.Mon, null, _tunerDevice.Name, out tmp);
   }
   catch (Exception)
   {
     Log.Log.WriteFile("analog: cannot add filter to graph");
     return false;
   }
   if (hr != 0)
   {
     Log.Log.Error("analog: AddTvTunerFilter failed:0x{0:X}", hr);
     throw new TvException("Unable to add tvtuner to graph");
   }
   _filterTvTuner = tmp;
   DevicesInUse.Instance.Add(_tunerDevice);
   _tuner = _filterTvTuner as IAMTVTuner;
   if (string.IsNullOrEmpty(graph.Tuner.Name) || !_tunerDevice.Name.Equals(
     graph.Tuner.Name))
   {
     Log.Log.WriteFile("analog: Detecting capabilities of the tuner");
     graph.Tuner.Name = _tunerDevice.Name;
     int index;
     _audioPin = FilterGraphTools.FindMediaPin(_filterTvTuner, MediaType.AnalogAudio, MediaSubType.Null,
                                               PinDirection.Output, out index);
     graph.Tuner.AudioPin = index;
     return CheckCapabilities(graph);
   }
   Log.Log.WriteFile("analog: Using stored capabilities of the tuner");
   _audioPin = DsFindPin.ByDirection(_filterTvTuner, PinDirection.Output, graph.Tuner.AudioPin);
   _supportsFMRadio = (graph.Tuner.RadioMode & RadioMode.FM) != 0;
   _supportsAMRadio = (graph.Tuner.RadioMode & RadioMode.AM) != 0;
   return true;
 }
Ejemplo n.º 10
0
    /// <summary>
    /// Creates the teletext component in the graph. First we try to use the stored informations in the graph
    /// </summary>
    /// <param name="graph">The stored graph</param>
    /// <param name="graphBuilder">The graphbuilder</param>
    /// <param name="capture">The capture component</param>
    /// <returns>true, if the building was successful; false otherwise</returns>
    public bool CreateFilterInstance(Graph graph, IFilterGraph2 graphBuilder, Capture capture)
    {
      Log.Log.WriteFile("analog: SetupTeletext()");
      Guid guidBaseFilter = typeof (IBaseFilter).GUID;
      object obj;
      //find and add tee/sink to sink filter
      DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSSplitter);
      devices[0].Mon.BindToObject(null, null, ref guidBaseFilter, out obj);
      _teeSink = (IBaseFilter)obj;
      int hr = graphBuilder.AddFilter(_teeSink, devices[0].Name);
      if (hr != 0)
      {
        Log.Log.Error("analog:SinkGraphEx.SetupTeletext(): Unable to add tee/sink filter");
        return false;
      }
      //connect capture filter -> tee sink filter
      IPin pin = DsFindPin.ByDirection(_teeSink, PinDirection.Input, 0);
      hr = graphBuilder.Connect(capture.VBIPin, pin);
      Release.ComObject(pin);
      if (hr != 0)
      {
        //failed...
        Log.Log.Error("analog: unable  to connect capture->tee/sink");
        graphBuilder.RemoveFilter(_teeSink);
        Release.ComObject(_teeSink);
        _teeSink = _filterWstDecoder = null;
        return false;
      }
      if (!string.IsNullOrEmpty(graph.Teletext.Name))
      {
        Log.Log.WriteFile("analog: Using Teletext-Component configuration from stored graph");
        devices = DsDevice.GetDevicesOfCat(graph.Teletext.Category);
        foreach (DsDevice device in devices)
        {
          if (device.Name != null && device.Name.Equals(graph.Teletext.Name))
          {
            //found it, add it to the graph
            Log.Log.Info("analog:Using teletext component - {0}", graph.Teletext.Name);
            device.Mon.BindToObject(null, null, ref guidBaseFilter, out obj);
            _filterWstDecoder = (IBaseFilter)obj;
            hr = graphBuilder.AddFilter(_filterWstDecoder, device.Name);
            if (hr != 0)
            {
              //failed...
              Log.Log.Error("analog:SinkGraphEx.SetupTeletext(): Unable to add WST Codec filter");
              graphBuilder.RemoveFilter(_filterWstDecoder);
              _filterWstDecoder = null;
            }
            break;
          }
        }
      }
      if (_filterWstDecoder == null)
      {
        Log.Log.WriteFile("analog: No stored or invalid graph for Teletext component - Trying to detect");

        //find the WST codec filter
        devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSVBICodec);
        foreach (DsDevice device in devices)
        {
          if (device.Name != null && device.Name.IndexOf("WST") >= 0)
          {
            //found it, add it to the graph
            Log.Log.Info("analog:Found WST Codec filter");
            device.Mon.BindToObject(null, null, ref guidBaseFilter, out obj);
            _filterWstDecoder = (IBaseFilter)obj;
            hr = graphBuilder.AddFilter(_filterWstDecoder, device.Name);
            if (hr != 0)
            {
              //failed...
              Log.Log.Error("analog:Unable to add WST Codec filter");
              graphBuilder.RemoveFilter(_teeSink);
              Release.ComObject(_teeSink);
              _teeSink = _filterWstDecoder = null;
              return false;
            }
            graph.Teletext.Name = device.Name;
            graph.Teletext.Category = FilterCategory.AMKSVBICodec;
            break;
          }
        }
        //Look for VBI Codec for Vista users as Vista doesn't use WST Codec anymore
        if (_filterWstDecoder == null)
        {
          devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSMULTIVBICodec);
          foreach (DsDevice device in devices)
            if (device.Name != null && device.Name.IndexOf("VBI") >= 0)
            {
              //found it, add it to the graph
              Log.Log.Info("analog:Found VBI Codec filter");
              device.Mon.BindToObject(null, null, ref guidBaseFilter, out obj);
              _filterWstDecoder = (IBaseFilter)obj;
              hr = graphBuilder.AddFilter(_filterWstDecoder, device.Name);
              if (hr != 0)
              {
                //failed...
                Log.Log.Error("analog:Unable to add VBI Codec filter");
                graphBuilder.RemoveFilter(_teeSink);
                Release.ComObject(_teeSink);
                _teeSink = _filterWstDecoder = null;
                return false;
              }
              graph.Teletext.Name = device.Name;
              graph.Teletext.Category = FilterCategory.AMKSMULTIVBICodec;
              break;
            }
        }
      }
      if (_filterWstDecoder == null)
      {
        Log.Log.Error("analog: unable to find WST Codec or VBI Codec filter");
        graphBuilder.RemoveFilter(_teeSink);
        Release.ComObject(_teeSink);
        _teeSink = _filterWstDecoder = null;
        return false;
      }
      //connect tee sink filter-> wst codec filter
      IPin pinOut = DsFindPin.ByDirection(_teeSink, PinDirection.Output, 0);
      pin = DsFindPin.ByDirection(_filterWstDecoder, PinDirection.Input, 0);
      hr = graphBuilder.Connect(pinOut, pin);
      Release.ComObject(pin);
      Release.ComObject(pinOut);
      if (hr != 0)
      {
        //failed
        Log.Log.Error("analog: unable  to tee/sink->wst codec");
        graphBuilder.RemoveFilter(_filterWstDecoder);
        graphBuilder.RemoveFilter(_teeSink);
        Release.ComObject(_filterWstDecoder);
        Release.ComObject(_teeSink);
        _teeSink = _filterWstDecoder = null;
        _teeSink = null;
        graph.Teletext.Name = null;
        graph.Teletext.Category = new Guid();
        return false;
      }
      //done
      Log.Log.WriteFile("analog: teletext setup");

      if (_filterWstDecoder != null)
      {
        Log.Log.WriteFile("analog:connect wst/vbi codec->tsfilesink");
        _pinWST_VBI = DsFindPin.ByDirection(_filterWstDecoder, PinDirection.Output, 0);
      }

      return true;
    }