/// <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;
    }
Example #2
0
 /// <summary>
 /// Creates the instance by parsing the Capture node in the configuration file
 /// </summary>
 /// <param name="xmlNode">The TvAudio xml node</param>
 /// <returns>TvAudio instance</returns>
 public static Capture CreateInstance(XmlNode xmlNode)
 {
   Capture capture = new Capture();
   Dictionary<VideoProcAmpProperty, VideoQuality> videoProcAmpValues =
     new Dictionary<VideoProcAmpProperty, VideoQuality>();
   capture.VideoProcAmpValues = videoProcAmpValues;
   if (xmlNode != null)
   {
     XmlNode viceoCaptureNode = xmlNode.SelectSingleNode("videoCapture");
     XmlNode nameNode = viceoCaptureNode.SelectSingleNode("name");
     XmlNode videoInNode = viceoCaptureNode.SelectSingleNode("videoIn");
     XmlNode audioInNode = viceoCaptureNode.SelectSingleNode("audioIn");
     XmlNode teletextPinNode = viceoCaptureNode.SelectSingleNode("teletextPin");
     XmlNode frameRateNode = viceoCaptureNode.SelectSingleNode("frameRate");
     XmlNode imageResolutionNode = viceoCaptureNode.SelectSingleNode("imageResolution");
     XmlNode availableVideoStandardNode = viceoCaptureNode.SelectSingleNode("videoStandard/available");
     XmlNode currentVideoStandardNode = viceoCaptureNode.SelectSingleNode("videoStandard/selected");
     string resolution = imageResolutionNode.InnerText;
     try
     {
       capture.TeletextPin = Int32.Parse(teletextPinNode.InnerText);
       capture.FrameRate = Double.Parse(frameRateNode.InnerText, CultureInfo.GetCultureInfo("en-GB").NumberFormat);
       capture.VideoIn = Int32.Parse(videoInNode.InnerText);
       if (audioInNode != null)
       {
         capture.AudioCaptureName = nameNode.InnerText;
       }
       else
       {
         XmlNode audioCaptureNode = xmlNode.SelectSingleNode("audioCapture");
         XmlNode audioCaptureNameNode = audioCaptureNode.SelectSingleNode("audioIn");
         audioInNode = audioCaptureNameNode.SelectSingleNode("audioIn");
         capture.AudioCaptureName = audioCaptureNameNode.InnerText;
       }
       capture.AudioIn = Int32.Parse(audioInNode.InnerText);
       if (resolution != null)
       {
         string[] imageResolutions = resolution.Split('x');
         capture.ImageWidth = Int32.Parse(imageResolutions[0]);
         capture.ImageHeight = Int32.Parse(imageResolutions[1]);
       }
       capture.CurrentVideoStandard = (AnalogVideoStandard)Int32.Parse(currentVideoStandardNode.InnerText);
       capture.AvailableVideoStandard = (AnalogVideoStandard)Int32.Parse(availableVideoStandardNode.InnerText);
       XmlNodeList videoQualityList = viceoCaptureNode.SelectSingleNode("videoProcAmp").SelectNodes("videoQuality");
       if (videoQualityList != null)
       {
         foreach (XmlNode pin in videoQualityList)
         {
           int minValue = Int32.Parse(pin.Attributes["minValue"].Value);
           int maxValue = Int32.Parse(pin.Attributes["maxValue"].Value);
           int defaultValue = Int32.Parse(pin.Attributes["defaultValue"].Value);
           int delta = Int32.Parse(pin.Attributes["delta"].Value);
           VideoProcAmpFlags flags = (VideoProcAmpFlags)Int32.Parse(pin.Attributes["flags"].Value);
           int value = Int32.Parse(pin.Attributes["value"].Value);
           VideoProcAmpProperty property = (VideoProcAmpProperty)Int32.Parse(pin.InnerText);
           VideoQuality quality = new VideoQuality(minValue, maxValue, delta, defaultValue,
                                                   flags == VideoProcAmpFlags.Manual, value);
           videoProcAmpValues.Add(property, quality);
         }
       }
     }
     catch
     {
       return capture;
     }
     capture.Name = nameNode.InnerText;
   }
   return capture;
 }