/// <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; }
/// <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; }