private void Config()
        {
            int hr = 0;

            graphBuilder = (IFilterGraph2) new FilterGraph();
            rot          = new DsROTEntry(graphBuilder);

            DsDevice[]  devices;
            IBaseFilter filter;
            IPin        pin;

            devices = DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory);
//      devices = DsDevice.GetDevicesOfCat(FilterCategory.BDARenderingFiltersCategory);
//      devices = DsDevice.GetDevicesOfCat(FilterCategory.BDAReceiverComponentsCategory);
//      devices = DsDevice.GetDevicesOfCat(FilterCategory.BDANetworkProvidersCategory);

            foreach (DsDevice device in devices)
            {
                hr = graphBuilder.AddSourceFilterForMoniker(device.Mon, null, device.Name, out filter);
                DsError.ThrowExceptionForHR(hr);

                pin = DsFindPin.ByDirection(filter, PinDirection.Input, 0);
                if (pin is IBDA_PinControl)
                {
                    pinControl = (IBDA_PinControl)pin;
                    return;
                }
                Marshal.ReleaseComObject(pin);

                pin = DsFindPin.ByDirection(filter, PinDirection.Output, 0);
                if (pin is IBDA_PinControl)
                {
                    pinControl = (IBDA_PinControl)pin;
                    return;
                }
                Marshal.ReleaseComObject(pin);

                hr = graphBuilder.RemoveFilter(filter);
                DsError.ThrowExceptionForHR(hr);

                Marshal.ReleaseComObject(filter);
            }
        }
Exemple #2
0
        private void AddAndConnectBDABoardFilters()
        {
            int hr = 0;

            DsDevice[] devices;

            ICaptureGraphBuilder2 capBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

            capBuilder.SetFiltergraph(this.graphBuilder);

            try
            {
                // Enumerate BDA Source filters category and found one that can connect to the network provider
                devices = DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory);
                for (int i = 0; i < devices.Length; i++)
                {
                    IBaseFilter tmp;

                    hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
                    DsError.ThrowExceptionForHR(hr);

                    hr = capBuilder.RenderStream(null, null, this.networkProvider, null, tmp);
                    if (hr == 0)
                    {
                        // Got it !
                        this.tuner = tmp;
                        break;
                    }
                    else
                    {
                        // Try another...
                        hr = graphBuilder.RemoveFilter(tmp);
                        Marshal.ReleaseComObject(tmp);
                    }
                }

                if (this.tuner == null)
                {
                    throw new ApplicationException("Can't find a valid BDA tuner");
                }

                // trying to connect this filter to the MPEG-2 Demux
                hr = capBuilder.RenderStream(null, null, tuner, null, mpeg2Demux);
                if (hr >= 0)
                {
                    // this is a one filter model
                    this.demodulator = null;
                    this.capture     = null;
                    return;
                }
                else
                {
                    // Then enumerate BDA Receiver Components category to found a filter connecting
                    // to the tuner and the MPEG2 Demux
                    devices = DsDevice.GetDevicesOfCat(FilterCategory.BDAReceiverComponentsCategory);

                    for (int i = 0; i < devices.Length; i++)
                    {
                        IBaseFilter tmp;

                        hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
                        DsError.ThrowExceptionForHR(hr);

                        hr = capBuilder.RenderStream(null, null, this.tuner, null, tmp);
                        if (hr == 0)
                        {
                            // Got it !
                            this.capture = tmp;

                            // Connect it to the MPEG-2 Demux
                            hr = capBuilder.RenderStream(null, null, this.capture, null, this.mpeg2Demux);
                            if (hr >= 0)
                            {
                                // This second filter connect both with the tuner and the demux.
                                // This is a capture filter...
                                return;
                            }
                            else
                            {
                                // This second filter connect with the tuner but not with the demux.
                                // This is in fact a demodulator filter. We now must find the true capture filter...

                                this.demodulator = this.capture;
                                this.capture     = null;

                                // saving the Demodulator's DevicePath to avoid creating it twice.
                                string demodulatorDevicePath = devices[i].DevicePath;

                                for (int j = 0; i < devices.Length; j++)
                                {
                                    if (devices[j].DevicePath.Equals(demodulatorDevicePath))
                                    {
                                        continue;
                                    }

                                    hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
                                    DsError.ThrowExceptionForHR(hr);

                                    hr = capBuilder.RenderStream(null, null, this.demodulator, null, tmp);
                                    if (hr == 0)
                                    {
                                        // Got it !
                                        this.capture = tmp;

                                        // Connect it to the MPEG-2 Demux
                                        hr = capBuilder.RenderStream(null, null, this.capture, null, this.mpeg2Demux);
                                        if (hr >= 0)
                                        {
                                            // This second filter connect both with the demodulator and the demux.
                                            // This is a true capture filter...
                                            return;
                                        }
                                    }
                                    else
                                    {
                                        // Try another...
                                        hr = graphBuilder.RemoveFilter(tmp);
                                        Marshal.ReleaseComObject(tmp);
                                    }
                                } // for j

                                // We have a tuner and a capture/demodulator that don't connect with the demux
                                // and we found no additionals filters to build a working filters chain.
                                throw new ApplicationException("Can't find a valid BDA filter chain");
                            }
                        }
                        else
                        {
                            // Try another...
                            hr = graphBuilder.RemoveFilter(tmp);
                            Marshal.ReleaseComObject(tmp);
                        }
                    } // for i

                    // We have a tuner that connect to the Network Provider BUT not with the demux
                    // and we found no additionals filters to build a working filters chain.
                    throw new ApplicationException("Can't find a valid BDA filter chain");
                }
            }
            finally
            {
                Marshal.ReleaseComObject(capBuilder);
            }
        }
Exemple #3
0
        /// <summary>
        /// Enumerate all tvcard devices and add them to the list
        /// </summary>
        private void DetectCards()
        {
            ITunerCap _providerType;
            bool      genericNP = false;

            //SkyStar 2 & IP Streaming
            DsDevice[] devices = DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory);
            for (int i = 0; i < devices.Length; ++i)
            {
                if (String.Compare(devices[i].Name, "B2C2 MPEG-2 Source", true) == 0)
                {
                    Log.Log.WriteFile("Detected SkyStar 2 card");
                    TvCardDvbSS2 card = new TvCardDvbSS2(_epgEvents, devices[i]);
                    _cards.Add(card);
                    //break;  maybe more than one B2C2 card ?
                }
                else if (String.Compare(devices[i].Name, "Elecard NWSource-Plus", true) == 0)
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting         setting;
                    setting = layer.GetSetting("iptvCardCount", "1");
                    int iptvCardCount = Convert.ToInt32(setting.Value);
                    for (int cardNum = 0; cardNum < iptvCardCount; cardNum++)
                    {
                        Log.Log.WriteFile("Detected IP TV Card " + cardNum);
                        TvCardDVBIP card = new TvCardDVBIPElecard(_epgEvents, devices[i], cardNum);
                        _cards.Add(card);
                    }
                }
                else if (String.Compare(devices[i].Name, "MediaPortal IPTV Source Filter", true) == 0)
                {
                    TvBusinessLayer layer = new TvBusinessLayer();
                    Setting         setting;
                    setting = layer.GetSetting("iptvCardCount", "1");
                    int iptvCardCount = Convert.ToInt32(setting.Value);
                    for (int cardNum = 0; cardNum < iptvCardCount; cardNum++)
                    {
                        Log.Log.WriteFile("Detected IP TV Card " + cardNum);
                        TvCardDVBIP card = new TvCardDVBIPBuiltIn(_epgEvents, devices[i], cardNum);
                        _cards.Add(card);
                    }
                }
            }
            //Hauppauge HD PVR & Colossus
            devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSCrossbar);
            for (int i = 0; i < devices.Length; ++i)
            {
                if (devices[i].Name == null)
                {
                    continue;
                }
                if (devices[i].Name.Equals("Hauppauge HD PVR Crossbar"))
                {
                    Log.Log.WriteFile("Detected Hauppauge HD PVR");
                    TvCardHDPVR card = new TvCardHDPVR(devices[i]);
                    _cards.Add(card);
                }
                else if (devices[i].Name.Contains("Hauppauge Colossus Crossbar"))
                {
                    Log.Log.WriteFile("Detected Hauppauge Colossus");
                    TvCardHDPVR card = new TvCardHDPVR(devices[i]);
                    _cards.Add(card);
                }
            }
            //BDA TV devices
            devices = DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory);
            if (devices.Length > 0)
            {
                IFilterGraph2 graphBuilder = (IFilterGraph2) new FilterGraph();
                DsROTEntry    rotEntry     = new DsROTEntry(graphBuilder);

                Guid networkProviderClsId = new Guid("{D7D42E5C-EB36-4aad-933B-B4C419429C98}");
                if (FilterGraphTools.IsThisComObjectInstalled(networkProviderClsId))
                {
                    handleInternalNetworkProviderFilter(devices, graphBuilder, networkProviderClsId, rotEntry);
                }
                else
                {
                    ITuningSpace tuningSpace = null;
                    ILocator     locator     = null;

                    //DVBT
                    IBaseFilter networkDVBT = null;
                    try
                    {
                        networkProviderClsId = typeof(DVBTNetworkProvider).GUID;
                        networkDVBT          = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                                   "DVBT Network Provider");
                        tuningSpace = (ITuningSpace) new DVBTuningSpace();
                        tuningSpace.put_UniqueName("DVBT TuningSpace");
                        tuningSpace.put_FriendlyName("DVBT TuningSpace");
                        tuningSpace.put__NetworkType(typeof(DVBTNetworkProvider).GUID);
                        ((IDVBTuningSpace)tuningSpace).put_SystemType(DVBSystemType.Terrestrial);
                        locator = (ILocator) new DVBTLocator();
                        locator.put_CarrierFrequency(-1);
                        locator.put_InnerFEC(FECMethod.MethodNotSet);
                        locator.put_InnerFECRate(BinaryConvolutionCodeRate.RateNotSet);
                        locator.put_Modulation(ModulationType.ModNotSet);
                        locator.put_OuterFEC(FECMethod.MethodNotSet);
                        locator.put_OuterFECRate(BinaryConvolutionCodeRate.RateNotSet);
                        locator.put_SymbolRate(-1);
                        tuningSpace.put_DefaultLocator(locator);
                        ((ITuner)networkDVBT).put_TuningSpace(tuningSpace);
                    }
                    catch (Exception ex)
                    {
                        Log.Log.Error("DVBT card detection error: {0}", ex.ToString());
                    }

                    //DVBS
                    networkProviderClsId = typeof(DVBSNetworkProvider).GUID;
                    IBaseFilter networkDVBS = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                                  "DVBS Network Provider");
                    tuningSpace = (ITuningSpace) new DVBSTuningSpace();
                    tuningSpace.put_UniqueName("DVBS TuningSpace");
                    tuningSpace.put_FriendlyName("DVBS TuningSpace");
                    tuningSpace.put__NetworkType(typeof(DVBSNetworkProvider).GUID);
                    ((IDVBSTuningSpace)tuningSpace).put_SystemType(DVBSystemType.Satellite);
                    locator = (ILocator) new DVBTLocator();
                    locator.put_CarrierFrequency(-1);
                    locator.put_InnerFEC(FECMethod.MethodNotSet);
                    locator.put_InnerFECRate(BinaryConvolutionCodeRate.RateNotSet);
                    locator.put_Modulation(ModulationType.ModNotSet);
                    locator.put_OuterFEC(FECMethod.MethodNotSet);
                    locator.put_OuterFECRate(BinaryConvolutionCodeRate.RateNotSet);
                    locator.put_SymbolRate(-1);
                    tuningSpace.put_DefaultLocator(locator);
                    ((ITuner)networkDVBS).put_TuningSpace(tuningSpace);

                    //ATSC
                    networkProviderClsId = typeof(ATSCNetworkProvider).GUID;
                    IBaseFilter networkATSC = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                                  "ATSC Network Provider");
                    tuningSpace = (ITuningSpace) new ATSCTuningSpace();
                    tuningSpace.put_UniqueName("ATSC TuningSpace");
                    tuningSpace.put_FriendlyName("ATSC TuningSpace");
                    ((IATSCTuningSpace)tuningSpace).put_MaxChannel(10000);
                    ((IATSCTuningSpace)tuningSpace).put_MaxMinorChannel(10000);
                    ((IATSCTuningSpace)tuningSpace).put_MinChannel(0);
                    ((IATSCTuningSpace)tuningSpace).put_MinMinorChannel(0);
                    ((IATSCTuningSpace)tuningSpace).put_MinPhysicalChannel(0);
                    ((IATSCTuningSpace)tuningSpace).put_InputType(TunerInputType.Antenna);
                    locator = (IATSCLocator) new ATSCLocator();
                    locator.put_CarrierFrequency(-1);
                    locator.put_InnerFEC(FECMethod.MethodNotSet);
                    locator.put_InnerFECRate(BinaryConvolutionCodeRate.RateNotSet);
                    locator.put_Modulation(ModulationType.ModNotSet);
                    locator.put_OuterFEC(FECMethod.MethodNotSet);
                    locator.put_OuterFECRate(BinaryConvolutionCodeRate.RateNotSet);
                    locator.put_SymbolRate(-1);
                    locator.put_CarrierFrequency(-1);
                    ((IATSCLocator)locator).put_PhysicalChannel(-1);
                    ((IATSCLocator)locator).put_TSID(-1);
                    tuningSpace.put_DefaultLocator(locator);
                    ((ITuner)networkATSC).put_TuningSpace(tuningSpace);

                    //DVBC
                    networkProviderClsId = typeof(DVBCNetworkProvider).GUID;
                    IBaseFilter networkDVBC = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                                  "DVBC Network Provider");
                    tuningSpace = (ITuningSpace) new DVBTuningSpace();
                    tuningSpace.put_UniqueName("DVBC TuningSpace");
                    tuningSpace.put_FriendlyName("DVBC TuningSpace");
                    tuningSpace.put__NetworkType(typeof(DVBCNetworkProvider).GUID);
                    ((IDVBTuningSpace)tuningSpace).put_SystemType(DVBSystemType.Cable);
                    locator = (ILocator) new DVBCLocator();
                    locator.put_CarrierFrequency(-1);
                    locator.put_InnerFEC(FECMethod.MethodNotSet);
                    locator.put_InnerFECRate(BinaryConvolutionCodeRate.RateNotSet);
                    locator.put_Modulation(ModulationType.ModNotSet);
                    locator.put_OuterFEC(FECMethod.MethodNotSet);
                    locator.put_OuterFECRate(BinaryConvolutionCodeRate.RateNotSet);
                    locator.put_SymbolRate(-1);
                    tuningSpace.put_DefaultLocator(locator);
                    ((ITuner)networkDVBC).put_TuningSpace(tuningSpace);

                    //MS Network Provider - MCE Roll-up 2 or better
                    networkProviderClsId = typeof(NetworkProvider).GUID;
                    // First test if the Generic Network Provider is available (only on MCE 2005 + Update Rollup 2)
                    if (FilterGraphTools.IsThisComObjectInstalled(networkProviderClsId))
                    {
                        genericNP = true;
                    }
                    for (int i = 0; i < devices.Length; i++)
                    {
                        bool   connected        = false;
                        bool   isCablePreferred = false;
                        string name             = devices[i].Name ?? "unknown";
                        name = name.ToLowerInvariant();
                        Log.Log.WriteFile("Found card:{0}", name);
                        //silicondust work-around for dvb type detection issue. generic provider would always use dvb-t
                        if (name.Contains("silicondust hdhomerun tuner"))
                        {
                            isCablePreferred = CheckHDHomerunCablePrefered(name);
                            Log.Log.WriteFile("silicondust hdhomerun detected - prefer cable mode: {0}", isCablePreferred);
                        }
                        IBaseFilter tmp;
                        try
                        {
                            graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, name, out tmp);
                        }
                        catch (InvalidComObjectException)
                        {
                            //ignore bad card
                            Log.Log.WriteFile("cannot add filter {0} to graph", devices[i].Name);
                            continue;
                        }
                        //Use the Microsoft Network Provider method first but only if available
                        if (genericNP)
                        {
                            IBaseFilter networkDVB = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                                         "Microsoft Network Provider");
                            if (ConnectFilter(graphBuilder, networkDVB, tmp))
                            {
                                Log.Log.WriteFile("Detected DVB card:{0}", name);
                                // determine the DVB card supported GUIDs here!
                                _providerType = networkDVB as ITunerCap;
                                int    ulcNetworkTypesMax = 5;
                                int    pulcNetworkTypes;
                                Guid[] pguidNetworkTypes = new Guid[ulcNetworkTypesMax];
                                int    hr = _providerType.get_SupportedNetworkTypes(ulcNetworkTypesMax, out pulcNetworkTypes,
                                                                                    pguidNetworkTypes);
                                for (int n = 0; n < pulcNetworkTypes; n++)
                                {
                                    Log.Log.Debug("Detecting type by MSNP {0}: {1}", n, pguidNetworkTypes[n]);
                                    //test the first found guid to determine the DVB card type
                                    if (pguidNetworkTypes[n] == (typeof(DVBTNetworkProvider).GUID) && !isCablePreferred)
                                    {
                                        Log.Log.WriteFile("Detected DVB-T* card:{0}", name);
                                        TvCardDVBT dvbtCard = new TvCardDVBT(_epgEvents, devices[i]);
                                        _cards.Add(dvbtCard);
                                        connected = true;
                                    }
                                    else if (pguidNetworkTypes[n] == (typeof(DVBSNetworkProvider).GUID) && !isCablePreferred)
                                    {
                                        Log.Log.WriteFile("Detected DVB-S* card:{0}", name);
                                        TvCardDVBS dvbsCard = new TvCardDVBS(_epgEvents, devices[i]);
                                        _cards.Add(dvbsCard);
                                        connected = true;
                                    }
                                    else if (pguidNetworkTypes[n] == (typeof(DVBCNetworkProvider).GUID))
                                    {
                                        Log.Log.WriteFile("Detected DVB-C* card:{0}", name);
                                        TvCardDVBC dvbcCard = new TvCardDVBC(_epgEvents, devices[i]);
                                        _cards.Add(dvbcCard);
                                        connected = true;
                                    }
                                    else if (pguidNetworkTypes[n] == (typeof(ATSCNetworkProvider).GUID))
                                    {
                                        Log.Log.WriteFile("Detected ATSC* card:{0}", name);
                                        TvCardATSC dvbsCard = new TvCardATSC(_epgEvents, devices[i]);
                                        _cards.Add(dvbsCard);
                                        connected = true;
                                    }
                                    if (connected)
                                    {
                                        graphBuilder.RemoveFilter(tmp);
                                        Release.ComObject("tmp filter", tmp);
                                        break; // already found one, no need to continue
                                    }
                                    else if (n == (pulcNetworkTypes - 1))
                                    {
                                        Log.Log.WriteFile("Connected with generic MS Network Provider however network types don't match, using the original method");
                                    }
                                }
                            }
                            else
                            {
                                Log.Log.WriteFile("Not connected with generic MS Network Provider, using the original method");
                                connected = false;
                            }
                            graphBuilder.RemoveFilter(networkDVB);
                            Release.ComObject("ms provider", networkDVB);
                        }
                        if (!genericNP || !connected)
                        {
                            if (ConnectFilter(graphBuilder, networkDVBT, tmp))
                            {
                                Log.Log.WriteFile("Detected DVB-T card:{0}", name);
                                TvCardDVBT dvbtCard = new TvCardDVBT(_epgEvents, devices[i]);
                                _cards.Add(dvbtCard);
                            }
                            else if (ConnectFilter(graphBuilder, networkDVBC, tmp))
                            {
                                Log.Log.WriteFile("Detected DVB-C card:{0}", name);
                                TvCardDVBC dvbcCard = new TvCardDVBC(_epgEvents, devices[i]);
                                _cards.Add(dvbcCard);
                            }
                            else if (ConnectFilter(graphBuilder, networkDVBS, tmp))
                            {
                                Log.Log.WriteFile("Detected DVB-S card:{0}", name);
                                TvCardDVBS dvbsCard = new TvCardDVBS(_epgEvents, devices[i]);
                                _cards.Add(dvbsCard);
                            }
                            else if (ConnectFilter(graphBuilder, networkATSC, tmp))
                            {
                                Log.Log.WriteFile("Detected ATSC card:{0}", name);
                                TvCardATSC dvbsCard = new TvCardATSC(_epgEvents, devices[i]);
                                _cards.Add(dvbsCard);
                            }
                            graphBuilder.RemoveFilter(tmp);
                            Release.ComObject("tmp filter", tmp);
                        }
                    }
                    FilterGraphTools.RemoveAllFilters(graphBuilder);
                    Release.ComObject("dvbc provider", networkDVBC);
                    Release.ComObject("atsc provider", networkATSC);
                    Release.ComObject("dvbs provider", networkDVBS);
                    Release.ComObject("dvbt provider", networkDVBT);
                    rotEntry.Dispose();
                    Release.ComObject("graph builder", graphBuilder);
                }
            }
            //Analogue TV devices
            devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSTVTuner);
            for (int i = 0; i < devices.Length; i++)
            {
                string name = devices[i].Name ?? "unknown";
                name = name.ToLowerInvariant();
                Log.Log.WriteFile("Detected analog card:{0}", name);
                TvCardAnalog analogCard = new TvCardAnalog(devices[i]);
                _cards.Add(analogCard);
            }
            _cards.Add(new RadioWebStreamCard());
        }
Exemple #4
0
        private void handleInternalNetworkProviderFilter(DsDevice[] devices, IFilterGraph2 graphBuilder,
                                                         Guid networkProviderClsId, DsROTEntry rotEntry)
        {
            IDvbNetworkProvider interfaceNetworkProvider;
            TuningType          tuningTypes;

            for (int i = 0; i < devices.Length; i++)
            {
                bool   isCablePreferred = false;
                string name             = devices[i].Name ?? "unknown";
                name = name.ToLowerInvariant();
                Log.Log.WriteFile("Found card:{0}", name);
                //silicondust work-around for dvb type detection issue. generic provider would always use dvb-t
                if (name.Contains("silicondust hdhomerun tuner"))
                {
                    isCablePreferred = CheckHDHomerunCablePrefered(name);
                    Log.Log.WriteFile("silicondust hdhomerun detected - prefer cable mode: {0}", isCablePreferred);
                }
                IBaseFilter tmp;
                graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, name, out tmp);
                //Use the Microsoft Network Provider method first but only if available
                IBaseFilter networkDVB = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                             "MediaPortal Network Provider");
                interfaceNetworkProvider = (IDvbNetworkProvider)networkDVB;
                string hash = GetHash(devices[i].DevicePath);
                interfaceNetworkProvider.ConfigureLogging(GetFileName(devices[i].DevicePath), hash, LogLevelOption.Debug);
                if (ConnectFilter(graphBuilder, networkDVB, tmp))
                {
                    Log.Log.WriteFile("Detected DVB card:{0}- Hash: {1}", name, hash);
                    interfaceNetworkProvider.GetAvailableTuningTypes(out tuningTypes);
                    Log.Log.WriteFile("TuningTypes: " + tuningTypes);
                    // determine the DVB card supported GUIDs here!
                    if ((tuningTypes & TuningType.DvbT) != 0 && !isCablePreferred)
                    {
                        Log.Log.WriteFile("Detected DVB-T* card:{0}", name);
                        TvCardDVBT dvbtCard = new TvCardDVBT(_epgEvents, devices[i]);
                        _cards.Add(dvbtCard);
                    }
                    if ((tuningTypes & TuningType.DvbS) != 0 && !isCablePreferred)
                    {
                        Log.Log.WriteFile("Detected DVB-S* card:{0}", name);
                        TvCardDVBS dvbsCard = new TvCardDVBS(_epgEvents, devices[i]);
                        _cards.Add(dvbsCard);
                    }
                    if ((tuningTypes & TuningType.DvbC) != 0)
                    {
                        Log.Log.WriteFile("Detected DVB-C* card:{0}", name);
                        TvCardDVBC dvbcCard = new TvCardDVBC(_epgEvents, devices[i]);
                        _cards.Add(dvbcCard);
                    }
                    if ((tuningTypes & TuningType.Atsc) != 0 && !isCablePreferred)
                    {
                        Log.Log.WriteFile("Detected ATSC* card:{0}", name);
                        TvCardATSC dvbsCard = new TvCardATSC(_epgEvents, devices[i]);
                        _cards.Add(dvbsCard);
                    }
                }
                graphBuilder.RemoveFilter(tmp);
                Release.ComObject("tmp filter", tmp);
                graphBuilder.RemoveFilter(networkDVB);
                Release.ComObject("ms provider", networkDVB);
            }
            FilterGraphTools.RemoveAllFilters(graphBuilder);
            rotEntry.Dispose();
            Release.ComObject("graph builder", graphBuilder);
        }
Exemple #5
0
        protected virtual void AddRenderers(IFilterGraph2 graphBuilder)
        {
            int hr = 0;
            Guid iid = typeof(IBaseFilter).GUID;

            if (this.AudioRendererDevice != null)
            {
                try
                {
                    this.audioRenderer = null;

                    IBaseFilter tmp;

                    object o;
                    this.AudioRendererDevice.Mon.BindToObject(null, null, ref iid, out o);
                    tmp = o as IBaseFilter;

                    //Add the Video input device to the graph
                    hr = graphBuilder.AddFilter(tmp, this.AudioRendererDevice.Name);
                    if (hr >= 0)
                    {
                        // Got it !
                        this.audioRenderer = tmp;
                    }
                    else
                    {
                        // Try another...
                        int hr1 = graphBuilder.RemoveFilter(tmp);
                        Marshal.ReleaseComObject(tmp);
                        //DsError.ThrowExceptionForHR(hr);
                    }
                }
                catch { }
            }

            if (this.audioRenderer == null)
            {
                // Add default audio renderer
                this.audioRenderer = (IBaseFilter)new DSoundRender();
                hr = graphBuilder.AddFilter(this.audioRenderer, "DirectSound Renderer");
                ThrowExceptionForHR("Adding the DirectSound Renderer: ", hr);
            }

            // To see something

            if (useWPF)
            {
                // Get the SampleGrabber interface
                ISampleGrabber sampleGrabber = new SampleGrabber() as ISampleGrabber;
                this.videoRenderer = sampleGrabber as IBaseFilter;

                // Set the media type to Video
                AMMediaType media = new AMMediaType();
                media.majorType = MediaType.Video;
                //media.subType = MediaSubType.YUY2; // RGB24;
                //media.formatType = FormatType.Null;
                //media.sampleSize = 1;
                //media.temporalCompression = false;
                //media.fixedSizeSamples = false;
                //media.unkPtr = IntPtr.Zero;
                //media.formatType = FormatType.None;
                //media.formatSize = 0;
                //media.formatPtr = IntPtr.Zero;
                media.subType = MediaSubType.RGB32; // RGB24;
                media.formatType = FormatType.VideoInfo;
                hr = sampleGrabber.SetMediaType(media);
                ThrowExceptionForHR("Setting the MediaType on the SampleGrabber: ", hr);
                DsUtils.FreeAMMediaType(media);

                // Configure the samplegrabber
                hr = sampleGrabber.SetCallback(this, 1);
                DsError.ThrowExceptionForHR(hr);

                // Add the frame grabber to the graph
                hr = graphBuilder.AddFilter(this.videoRenderer, "SampleGrabber");
                ThrowExceptionForHR("Adding the SampleGrabber: ", hr);

                //hr = ConnectFilters(this.videoRenderer, nullRenderer);
            }
            else
            {
                try
                {
                    this.videoRenderer = (IBaseFilter)new EnhancedVideoRenderer();
                    hr = graphBuilder.AddFilter(this.videoRenderer, "Enhanced Video Renderer");
                    ThrowExceptionForHR("Adding the EVR: ", hr);
                    useEVR = true;
                }
                catch (Exception) { }
                if (!useEVR)
                {
                    this.videoRenderer = (IBaseFilter)new VideoMixingRenderer9();
                    hr = graphBuilder.AddFilter(this.videoRenderer, "Video Mixing Renderer 9");
                    ThrowExceptionForHR("Adding the VMR9: ", hr);
                }
            }
            //IReferenceClock clock = this.audioRenderer as IReferenceClock;
            //if(clock != null)
            //{
            //    // Set the graph clock.
            //    this.FilterGraph.SetDefaultSyncSource(
            //    pGraph->QueryInterface(IID_IMediaFilter, (void**)&pMediaFilter);
            //    pMediaFilter->SetSyncSource(pClock);
            //    pClock->Release();
            //    pMediaFilter->Release();
            //}
        }
    /// <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;
    }
Exemple #7
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;
 }
Exemple #8
0
        private void DetectSupportedBdaSourceDevices(ref HashSet <string> previouslyKnownDevices, ref HashSet <string> knownDevices)
        {
            Log.Log.Debug("Detect BDA source devices");

            // MS generic, MCE 2005 roll-up 2 or better
            bool isMsGenericNpAvailable = FilterGraphTools.IsThisComObjectInstalled(typeof(NetworkProvider).GUID);

            DsDevice[] connectedDevices = DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory);
            foreach (DsDevice connectedDevice in connectedDevices)
            {
                string name       = connectedDevice.Name;
                string devicePath = connectedDevice.DevicePath;
                if (string.IsNullOrEmpty(name) || string.IsNullOrEmpty(devicePath))
                {
                    continue;
                }
                if (previouslyKnownDevices.Contains(devicePath))
                {
                    knownDevices.Add(devicePath);
                    continue;
                }

                // North American CableCARD tuners [PBDA].
                if (name.StartsWith("HDHomeRun Prime") || name.StartsWith("Ceton InfiniTV"))
                {
                    Log.Log.Info("Detected new PBDA CableCARD tuner device {0} {1}", name, devicePath);
                    TunerPbdaCableCard cableCardTuner = new TunerPbdaCableCard(connectedDevice);
                    knownDevices.Add(devicePath);
                    _deviceEventListener.OnDeviceAdded(cableCardTuner);
                    continue;
                }

                IBaseFilter tmpDeviceFilter;
                try
                {
                    _graphBuilder.AddSourceFilterForMoniker(connectedDevice.Mon, null, name, out tmpDeviceFilter);
                }
                catch (Exception ex)
                {
                    Log.Log.Error("Failed to add filter to detect device type for {0}!\r\n{1}", name, ex);
                    continue;
                }

                try
                {
                    // Silicondust regular (non-CableCARD) HDHomeRun. Workaround for tuner type
                    // detection issue. The MS generic provider would always detect DVB-T.
                    bool isCablePreferred = false;
                    if (name.StartsWith("Silicondust HDHomeRun Tuner"))
                    {
                        isCablePreferred = GetHdHomeRunSourceType(name).Equals("Digital Cable");
                    }

                    Log.Log.Info("Detected new digital BDA tuner device {0} {1}", name, devicePath);

                    // Try the MediaPortal network provider first.
                    ITVCard deviceToAdd = null;
                    if (_mpNp != null)
                    {
                        Log.Log.Debug("  check type with MP NP");
                        IDvbNetworkProvider interfaceNetworkProvider = (IDvbNetworkProvider)_mpNp;
                        string hash = GetHash(devicePath);
                        interfaceNetworkProvider.ConfigureLogging(GetFileName(devicePath), hash, LogLevelOption.Debug);
                        if (ConnectFilter(_graphBuilder, _mpNp, tmpDeviceFilter))
                        {
                            TuningType tuningTypes;
                            interfaceNetworkProvider.GetAvailableTuningTypes(out tuningTypes);
                            Log.Log.Debug("  tuning types = {0}, hash = {1}", tuningTypes, hash);
                            if ((tuningTypes & TuningType.DvbT) != 0 && !isCablePreferred)
                            {
                                deviceToAdd = new TvCardDVBT(connectedDevice);
                            }
                            else if ((tuningTypes & TuningType.DvbS) != 0 && !isCablePreferred)
                            {
                                deviceToAdd = new TvCardDVBS(connectedDevice);
                            }
                            else if ((tuningTypes & TuningType.DvbC) != 0)
                            {
                                deviceToAdd = new TvCardDVBC(connectedDevice);
                            }
                            else if ((tuningTypes & TuningType.Atsc) != 0)
                            {
                                deviceToAdd = new TvCardATSC(connectedDevice);
                            }
                            else
                            {
                                Log.Log.Debug("  connected to MP NP but type not recognised");
                            }
                        }
                        else
                        {
                            Log.Log.Debug("  failed to connect to MP NP");
                        }
                    }
                    // Try the Microsoft network provider next if the MP NP
                    // failed and the MS generic NP is available.
                    if (deviceToAdd == null && isMsGenericNpAvailable)
                    {
                        // Note: the MS NP must be added/removed to/from the graph for each
                        // device that is checked. If you don't do this, the networkTypes
                        // list gets longer and longer and longer.
                        Log.Log.Debug("  check type with MS NP");
                        IBaseFilter genericNp = null;
                        try
                        {
                            genericNp = FilterGraphTools.AddFilterFromClsid(_graphBuilder, typeof(NetworkProvider).GUID, "Microsoft Network Provider");
                        }
                        catch
                        {
                            genericNp = null;
                        }
                        if (genericNp == null)
                        {
                            Log.Log.Error(" failed to add MS NP to graph");
                        }
                        else
                        {
                            if (ConnectFilter(_graphBuilder, genericNp, tmpDeviceFilter))
                            {
                                int    networkTypesMax = 5;
                                int    networkTypeCount;
                                Guid[] networkTypes = new Guid[networkTypesMax];
                                int    hr           = (genericNp as ITunerCap).get_SupportedNetworkTypes(networkTypesMax, out networkTypeCount, networkTypes);
                                Log.Log.Debug("  network type count = {0}", networkTypeCount);
                                for (int n = 0; n < networkTypeCount; n++)
                                {
                                    Log.Log.Debug("  network type {0} = {1}", n, networkTypes[n]);
                                }
                                for (int n = 0; n < networkTypeCount; n++)
                                {
                                    if (networkTypes[n] == typeof(DVBTNetworkProvider).GUID && !isCablePreferred)
                                    {
                                        deviceToAdd = new TvCardDVBT(connectedDevice);
                                    }
                                    else if (networkTypes[n] == typeof(DVBSNetworkProvider).GUID && !isCablePreferred)
                                    {
                                        deviceToAdd = new TvCardDVBS(connectedDevice);
                                    }
                                    else if (networkTypes[n] == typeof(DVBCNetworkProvider).GUID)
                                    {
                                        deviceToAdd = new TvCardDVBC(connectedDevice);
                                    }
                                    else if (networkTypes[n] == typeof(ATSCNetworkProvider).GUID)
                                    {
                                        deviceToAdd = new TvCardATSC(connectedDevice);
                                    }
                                    if (deviceToAdd != null)
                                    {
                                        break;
                                    }
                                    else if (n == (networkTypeCount - 1))
                                    {
                                        Log.Log.Debug(" connected to MS NP but type not recognised");
                                    }
                                }
                            }
                            else
                            {
                                Log.Log.Debug("  failed to connect to MS NP");
                            }

                            _graphBuilder.RemoveFilter(genericNp);
                            Release.ComObject("device detection generic network provider", genericNp);
                            genericNp = null;
                        }
                    }
                    // Last shot is the old style Microsoft network providers.
                    if (deviceToAdd == null)
                    {
                        Log.Log.Debug("  check type with specific NPs");
                        if (ConnectFilter(_graphBuilder, _dvbtNp, tmpDeviceFilter))
                        {
                            deviceToAdd = new TvCardDVBT(connectedDevice);
                        }
                        else if (ConnectFilter(_graphBuilder, _dvbcNp, tmpDeviceFilter))
                        {
                            deviceToAdd = new TvCardDVBC(connectedDevice);
                        }
                        else if (ConnectFilter(_graphBuilder, _dvbsNp, tmpDeviceFilter))
                        {
                            deviceToAdd = new TvCardDVBS(connectedDevice);
                        }
                        else if (ConnectFilter(_graphBuilder, _atscNp, tmpDeviceFilter))
                        {
                            deviceToAdd = new TvCardATSC(connectedDevice);
                        }
                        else
                        {
                            Log.Log.Debug("  failed to connect to specific NP");
                        }
                    }

                    if (deviceToAdd != null)
                    {
                        Log.Log.Info("  tuner type = {0}", deviceToAdd.CardType);
                        knownDevices.Add(devicePath);
                        _deviceEventListener.OnDeviceAdded(deviceToAdd);
                    }
                }
                finally
                {
                    _graphBuilder.RemoveFilter(tmpDeviceFilter);
                    Release.ComObject("device detection device filter", tmpDeviceFilter);
                }
            }
        }
        /// <summary>
        /// Creates the filter based on the configuration file
        /// </summary>
        /// <param name="tvAudio">The tvaudio component</param>
        /// <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>
        /// <param name="capBuilder">The Capture graph builder</param>
        /// <returns>true, if the graph building was successful</returns>
        private bool CreateConfigurationBasedFilterInstance(Graph graph, ICaptureGraphBuilder2 capBuilder,
                                                            IFilterGraph2 graphBuilder, Tuner tuner, Crossbar crossbar,
                                                            TvAudio tvAudio)
        {
            string audioDeviceName = graph.Capture.AudioCaptureName;
            string videoDeviceName = graph.Capture.Name;

            DsDevice[] devices;
            bool       videoConnected = false;
            bool       audioConnected = false;

            //get a list of all video capture devices
            try
            {
                if (tuner.TunerName == "Adaptec USB TvTuner")
                {
                    Log.Log.WriteFile("analog: Adaptec USB device detected!");
                    devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
                }
                else
                {
                    devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSCapture); //shouldn't be VideoInputDevice
                    devices = DeviceSorter.Sort(devices, tuner.TunerName, tvAudio.TvAudioName, crossbar.CrossBarName);
                }
            }
            catch (Exception)
            {
                Log.Log.WriteFile("analog: AddTvCaptureFiler error in allocating devices collection");
                return(false);
            }
            if (devices.Length == 0)
            {
                Log.Log.WriteFile("analog: AddTvCaptureFilter no tvcapture devices found");
                return(false);
            }
            //try each video capture filter
            for (int i = 0; i < devices.Length; i++)
            {
                bool        filterUsed = false;
                IBaseFilter tmp;
                if (_badCaptureDevices.Contains(devices[i].Name))
                {
                    Log.Log.WriteFile("analog: AddTvCaptureFilter bypassing: {0}", devices[i].Name);
                    continue;
                }
                Log.Log.WriteFile("analog: AddTvCaptureFilter try:{0} {1}", devices[i].Name, i);
                // if video capture filter is in use, then we can skip it
                if (DevicesInUse.Instance.IsUsed(devices[i]))
                {
                    Log.Log.WriteFile("analog: Device: {0} in use?", devices[i].Name);
                    continue;
                }
                if (!videoDeviceName.Equals(devices[i].Name) &&
                    (audioDeviceName == null || !audioDeviceName.Equals(devices[i].Name)))
                {
                    continue;
                }
                int hr;
                try
                {
                    // add video capture filter 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)
                {
                    //cannot add video capture filter to graph, try next one
                    if (tmp != null)
                    {
                        Log.Log.WriteFile("analog: cannot add filter: {0} to graph", devices[i].Name);
                        graphBuilder.RemoveFilter(tmp);
                        Release.ComObject("TvCaptureFilter", tmp);
                    }
                    continue;
                }
                // connect crossbar->video capture filter
                if (videoDeviceName.Equals(devices[i].Name) &&
                    FilterGraphTools.ConnectPin(graphBuilder, crossbar.VideoOut, tmp, graph.Capture.VideoIn))
                {
                    _filterVideoCapture = tmp;
                    _videoCaptureDevice = devices[i];
                    if (_audioCaptureDevice != _videoCaptureDevice)
                    {
                        DevicesInUse.Instance.Add(_videoCaptureDevice);
                    }
                    Log.Log.WriteFile("analog: AddTvCaptureFilter connected video to crossbar successfully");
                    videoConnected = true;
                    filterUsed     = true;
                }
                // crossbar->audio capture filter
                // Many video capture are also the audio capture filter, so we can always try it again
                if (audioDeviceName.Equals(devices[i].Name) &&
                    FilterGraphTools.ConnectPin(graphBuilder, crossbar.AudioOut, tmp, graph.Capture.AudioIn))
                {
                    _filterAudioCapture = tmp;
                    _audioCaptureDevice = devices[i];
                    if (_audioCaptureDevice != _videoCaptureDevice)
                    {
                        DevicesInUse.Instance.Add(_audioCaptureDevice);
                    }
                    Log.Log.WriteFile("analog: AddTvCaptureFilter connected audio to crossbar successfully");
                    audioConnected = true;
                    filterUsed     = true;
                }
                // _audioCaptureDevice should never be null - avoids null exception crashes with Encoder.cs
                else
                {
                    _audioCaptureDevice = devices[i];
                }

                if (!filterUsed)
                {
                    // cannot connect crossbar->video capture filter, remove filter from graph
                    // cand continue with the next vieo capture filter
                    Log.Log.WriteFile("analog: AddTvCaptureFilter failed to connect to crossbar");
                    graphBuilder.RemoveFilter(tmp);
                    Release.ComObject("capture filter", tmp);
                }
                else
                {
                    i = -1; // Go through the devices again from the start...
                }
                if (videoConnected && audioConnected)
                {
                    break;
                }
            }
            if (_filterVideoCapture != null)
            {
                if (graph.Capture.TeletextPin != -1)
                {
                    _pinVBI = DsFindPin.ByDirection(_filterVideoCapture, PinDirection.Output,
                                                    graph.Capture.TeletextPin);
                }
                _videoProcAmp              = _filterVideoCapture as IAMVideoProcAmp;
                _analogVideoDecoder        = _filterVideoCapture as IAMAnalogVideoDecoder;
                _streamConfig              = _filterVideoCapture as IAMStreamConfig;
                _videoFormats              = graph.Capture.AvailableVideoStandard;
                _defaultVideoProcAmpValues = graph.Capture.VideoProcAmpValues;
                _frameRate   = graph.Capture.FrameRate;
                _imageWidth  = graph.Capture.ImageWidth;
                _imageHeight = graph.Capture.ImageHeight;
                CheckCapabilitiesStreamConfig(graph, capBuilder);
                SetCaptureConfiguration(graph);
            }
            return(_filterVideoCapture != null);
        }
    /// <summary>
    /// Adds the video compressor.
    /// </summary>
    /// <param name="_graphBuilder">GraphBuilder</param>
    /// <returns></returns>
    private bool AddVideoCompressor(IFilterGraph2 _graphBuilder)
    {
      Log.Log.WriteFile("analog: AddVideoCompressor");
      DsDevice[] devices1 = DsDevice.GetDevicesOfCat(FilterCategory.VideoCompressorCategory);
      DsDevice[] devices2 = DsDevice.GetDevicesOfCat(FilterCategory.LegacyAmFilterCategory);
      IList<SoftwareEncoder> videoEncoders = _layer.GetSofwareEncodersVideo();
      DsDevice[] videoDevices = new DsDevice[videoEncoders.Count];
      for (int x = 0; x < videoEncoders.Count; ++x)
      {
        videoDevices[x] = null;
      }
      for (int i = 0; i < devices1.Length; i++)
      {
        for (int x = 0; x < videoEncoders.Count; ++x)
        {
          if (videoEncoders[x].Name == devices1[i].Name)
          {
            videoDevices[x] = devices1[i];
            break;
          }
        }
      }
      for (int i = 0; i < devices2.Length; i++)
      {
        for (int x = 0; x < videoEncoders.Count; ++x)
        {
          if (videoEncoders[x].Name == devices2[i].Name)
          {
            videoDevices[x] = devices2[i];
            break;
          }
        }
      }
      //for each compressor
      Log.Log.WriteFile("analog: AddVideoCompressor found:{0} compressor", videoDevices.Length);
      for (int i = 0; i < videoDevices.Length; i++)
      {
        IBaseFilter tmp;
        if (videoDevices[i] == null || !EncodersInUse.Instance.Add(videoDevices[i], videoEncoders[i]))
        {
          continue;
        }

        Log.Log.WriteFile("analog:  try compressor:{0}", videoDevices[i].Name);
        int hr;
        try
        {
          //add compressor filter to graph
          hr = _graphBuilder.AddSourceFilterForMoniker(videoDevices[i].Mon, null, videoDevices[i].Name, out tmp);
        }
        catch (Exception)
        {
          Log.Log.WriteFile("analog: cannot add compressor to graph");
          EncodersInUse.Instance.Remove(videoDevices[i]);
          continue;
        }
        if (hr != 0)
        {
          //failed to add filter to graph, continue with the next one
          if (tmp != null)
          {
            _graphBuilder.RemoveFilter(tmp);
            Release.ComObject("videocompressor", tmp);
          }
          EncodersInUse.Instance.Remove(videoDevices[i]);
          continue;
        }
        if (tmp == null)
        {
          EncodersInUse.Instance.Remove(videoDevices[i]);
          continue;
        }

        // check if this compressor filter has an mpeg audio output pin
        Log.Log.WriteFile("analog:  connect video pin->video compressor");
        IPin pinVideo = DsFindPin.ByDirection(tmp, PinDirection.Input, 0);
        // we found a nice compressor, lets try to connect the analog video pin to the compressor
        hr = _graphBuilder.Connect(_pinAnalogVideo, pinVideo);
        if (hr != 0)
        {
          Log.Log.WriteFile("analog: failed to connect video pin->video compressor");
          //unable to connec the pin, remove it and continue with next compressor
          _graphBuilder.RemoveFilter(tmp);
          Release.ComObject("videocompressor", tmp);
          EncodersInUse.Instance.Remove(videoDevices[i]);
          continue;
        }

        //succeeded.
        _videoCompressorDevice = videoDevices[i];
        _filterVideoCompressor = tmp;
        return true;
      }
      return false;
    }
    /// <summary>
    /// Adds one or 2 encoder filters to the graph
    ///  several posibilities
    ///  1. no encoder filter needed
    ///  2. single encoder filter with seperate audio/video inputs and 1 (mpeg-2) output
    ///  3. single encoder filter with a mpeg2 program stream input (I2S)
    ///  4. two encoder filters. one for audio and one for video
    ///
    ///  At the end of this method the graph looks like:
    ///
    ///  option 2: one encoder filter, with 2 inputs
    ///    [                ]----->[                ]
    ///    [ capture filter ]      [ encoder filter ]
    ///    [                ]----->[                ]
    ///
    ///
    ///  option 3: one encoder filter, with 1 input
    ///    [                ]      [                ]
    ///    [ capture filter ]----->[ encoder filter ]
    ///    [                ]      [                ]
    ///
    ///
    ///  option 4: 2 encoder filters one for audio and one for video
    ///    [                ]----->[   video        ]
    ///    [ capture filter ]      [ encoder filter ]
    ///    [                ]      [                ]
    ///    [                ]   
    ///    [                ]----->[   audio        ]
    ///                            [ encoder filter ]
    ///                            [                ]
    ///
    /// </summary>
    /// <param name="matchPinNames">if set to <c>true</c> the pin names of the encoder filter should match the pin names of the capture filter.</param>
    /// <param name="mpeg2ProgramFilter">if set to <c>true</c> than only encoders with an mpeg2 program output pins are accepted</param>
    /// <param name="_graphBuilder">GraphBuilder</param>
    /// <param name="_tuner">Tuner</param>
    /// <param name="_tvAudio">TvAudio</param>
    /// <param name="_crossbar">Crossbar</param>
    /// <param name="_capture">Capture</param>
    /// <returns>true if encoder filters are added, otherwise false</returns>
    private bool AddTvEncoderFilter(bool matchPinNames, bool mpeg2ProgramFilter, IFilterGraph2 _graphBuilder,
                                    Tuner _tuner, TvAudio _tvAudio, Crossbar _crossbar, Capture _capture)
    {
      Log.Log.WriteFile("analog: AddTvEncoderFilter - MatchPinNames: {0} - MPEG2ProgramFilter: {1}", matchPinNames,
                        mpeg2ProgramFilter);
      bool finished = false;
      DsDevice[] devices;
      // first get all encoder filters available on this system
      try
      {
        devices = DsDevice.GetDevicesOfCat(FilterCategory.WDMStreamingEncoderDevices);
        devices = DeviceSorter.Sort(devices, _tuner.TunerName, _tvAudio.TvAudioName, _crossbar.CrossBarName,
                                    _capture.VideoCaptureName, _capture.AudioCaptureName, _videoEncoderDevice,
                                    _audioEncoderDevice, _multiplexerDevice);
      }
      catch (Exception)
      {
        Log.Log.WriteFile("analog: AddTvEncoderFilter no encoder devices found (Exception)");
        return false;
      }
      if (devices == null)
      {
        Log.Log.WriteFile("analog: AddTvEncoderFilter no encoder devices found (devices == null)");
        return false;
      }
      if (devices.Length == 0)
      {
        Log.Log.WriteFile("analog: AddTvEncoderFilter no encoder devices found");
        return false;
      }
      //for each encoder
      Log.Log.WriteFile("analog: AddTvEncoderFilter found:{0} encoders", devices.Length);
      for (int i = 0; i < devices.Length; i++)
      {
        IBaseFilter tmp;
        //if encoder is in use, we can skip it
        if (DevicesInUse.Instance.IsUsed(devices[i]))
        {
          Log.Log.WriteFile("analog:  skip :{0} (inuse)", devices[i].Name);
          continue;
        }
        Log.Log.WriteFile("analog:  try encoder:{0} {1}", devices[i].Name, i);
        int hr;
        try
        {
          //add encoder filter to graph
          hr = _graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
        }
        catch (Exception)
        {
          Log.Log.WriteFile("analog: cannot add filter {0} to graph", devices[i].Name);
          continue;
        }
        if (hr != 0)
        {
          //failed to add filter to graph, continue with the next one
          if (tmp != null)
          {
            _graphBuilder.RemoveFilter(tmp);
            Release.ComObject("TvEncoderFilter", tmp);
          }
          continue;
        }
        if (tmp == null)
          continue;
        // Encoder has been added to the graph
        // Now some cards have 2 encoder types, one for mpeg-2 transport stream and one for
        // mpeg-2 program stream. We dont want the mpeg-2 transport stream !
        // So first we check the output pins...
        // and dont accept filters which have a mpeg-ts output pin..
        // get the output pin
        bool isTsFilter = mpeg2ProgramFilter;
        IPin pinOut = DsFindPin.ByDirection(tmp, PinDirection.Output, 0);
        if (pinOut != null)
        {
          //check which media types it support
          IEnumMediaTypes enumMediaTypes;
          pinOut.EnumMediaTypes(out enumMediaTypes);
          if (enumMediaTypes != null)
          {
            int fetched;
            AMMediaType[] mediaTypes = new AMMediaType[20];
            enumMediaTypes.Next(20, mediaTypes, out fetched);
            if (fetched > 0)
            {
              for (int media = 0; media < fetched; ++media)
              {
                //check if media is mpeg-2 transport
                if (mediaTypes[media].majorType == MediaType.Stream &&
                    mediaTypes[media].subType == MediaSubType.Mpeg2Transport)
                {
                  isTsFilter = true;
                }
                //check if media is mpeg-2 program
                if (mediaTypes[media].majorType == MediaType.Stream &&
                    mediaTypes[media].subType == MediaSubType.Mpeg2Program)
                {
                  isTsFilter = false;
                  break;
                }

                // NVTV dual tuner needs this one to make it work so dont skip it
                if (mediaTypes[media].majorType == MediaType.Video &&
                    mediaTypes[media].subType == new Guid("be626472-fe7c-4a21-9f0b-d8f18b5ab441")) /*MediaSubType.?? */
                {
                  isTsFilter = false;
                  break;
                }
              }
            }
          }
          Release.ComObject("pinout", pinOut);
        }
        //if encoder has mpeg-2 ts output pin, then we skip it and continue with the next one
        if (isTsFilter)
        {
          Log.Log.WriteFile("analog:  filter {0} does not have mpeg-2 ps output or is a mpeg-2 ts filters",
                            devices[i].Name);
          _graphBuilder.RemoveFilter(tmp);
          Release.ComObject("TvEncoderFilter", tmp);
          continue;
        }
        // get the input pins of the encoder (can be 1 or 2 inputs)
        IPin pin1 = DsFindPin.ByDirection(tmp, PinDirection.Input, 0);
        IPin pin2 = DsFindPin.ByDirection(tmp, PinDirection.Input, 1);
        if (pin1 != null)
          Log.Log.WriteFile("analog: encoder in-pin1:{0}", FilterGraphTools.LogPinInfo(pin1));
        if (pin2 != null)
          Log.Log.WriteFile("analog: encoder in-pin2:{0}", FilterGraphTools.LogPinInfo(pin2));
        // if the encoder has 2 input pins then this means it has seperate inputs for audio and video
        if (pin1 != null && pin2 != null)
        {
          // try to connect the capture device -> encoder filters..
          if (ConnectEncoderFilter(tmp, true, true, matchPinNames, _graphBuilder, _capture))
          {
            //succeeded, encoder has been added and we are done
            _filterVideoEncoder = tmp;
            _videoEncoderDevice = devices[i];
            DevicesInUse.Instance.Add(_videoEncoderDevice);
            Log.Log.WriteFile("analog: AddTvEncoderFilter succeeded (encoder with 2 inputs)");
            //            success = true;
            finished = true;
            tmp = null;
          }
        }
        else if (pin1 != null)
        {
          //encoder filter only has 1 input pin.
          //First we get the media type of this pin to determine if its audio of video
          IEnumMediaTypes enumMedia;
          AMMediaType[] media = new AMMediaType[20];
          int fetched;
          pin1.EnumMediaTypes(out enumMedia);
          enumMedia.Next(1, media, out fetched);
          if (fetched == 1)
          {
            //media type found
            Log.Log.WriteFile("analog: AddTvEncoderFilter encoder output major:{0} sub:{1}", media[0].majorType,
                              media[0].subType);
            //is it audio?
            if (media[0].majorType == MediaType.Audio)
            {
              //yes, pin is audio
              //then connect the encoder to the audio output pin of the capture filter
              if (ConnectEncoderFilter(tmp, false, true, matchPinNames, _graphBuilder, _capture))
              {
                //this worked. but we're not done yet. We probably need to add a video encoder also
                _filterAudioEncoder = tmp;
                _audioEncoderDevice = devices[i];
                DevicesInUse.Instance.Add(_audioEncoderDevice);
                //                success = true;
                Log.Log.WriteFile("analog: AddTvEncoderFilter succeeded (audio encoder)");
                // if video encoder was already added, then we're done.
                if (_filterVideoEncoder != null)
                  finished = true;
                tmp = null;
              }
            }
            else
            {
              //pin is video
              //then connect the encoder to the video output pin of the capture filter
              if (ConnectEncoderFilter(tmp, true, false, matchPinNames, _graphBuilder, _capture))
              {
                //this worked. but we're not done yet. We probably need to add a audio encoder also
                _filterVideoEncoder = tmp;
                _videoEncoderDevice = devices[i];
                DevicesInUse.Instance.Add(_videoEncoderDevice);
                //                success = true;
                Log.Log.WriteFile("analog: AddTvEncoderFilter succeeded (video encoder)");
                // if audio encoder was already added, then we're done.
                if (_filterAudioEncoder != null)
                  finished = true;
                tmp = null;
              }
            }
            DsUtils.FreeAMMediaType(media[0]);
          }
          else
          {
            // filter does not report any media type (which is strange)
            // we must do something, so we treat it as a video input pin
            Log.Log.WriteFile("analog: AddTvEncoderFilter no media types for pin1"); //??
            if (ConnectEncoderFilter(tmp, true, false, matchPinNames, _graphBuilder, _capture))
            {
              _filterVideoEncoder = tmp;
              _videoEncoderDevice = devices[i];
              DevicesInUse.Instance.Add(_videoEncoderDevice);
              //              success = true;
              Log.Log.WriteFile("analog: AddTvEncoderFilter succeeded");
              finished = true;
              tmp = null;
            }
          }
        }
        else
        {
          Log.Log.WriteFile("analog: AddTvEncoderFilter no pin1");
        }
        if (pin1 != null)
          Release.ComObject("encoder pin0", pin1);
        if (pin2 != null)
          Release.ComObject("encoder pin1", pin2);
        if (tmp != null)
        {
          _graphBuilder.RemoveFilter(tmp);
          Release.ComObject("encoder filter", tmp);
        }
        if (finished)
        {
          Log.Log.WriteFile("analog: AddTvEncoderFilter succeeded 3");
          return true;
        }
      } //for (int i = 0; i < devices.Length; i++)
      Log.Log.WriteFile("analog: AddTvEncoderFilter no encoder found");
      return false;
    }
    /// <summary>
    /// Adds the multiplexer filter to the graph.
    /// several posibilities
    ///  1. no tv multiplexer needed
    ///  2. tv multiplexer filter which is connected to a single encoder filter
    ///  3. tv multiplexer filter which is connected to two encoder filter (audio/video)
    ///  4. tv multiplexer filter which is connected to the capture filter
    /// at the end this method the graph looks like this:
    /// 
    ///  option 2: single encoder filter
    ///    [                ]----->[                ]      [             ]
    ///    [ capture filter ]      [ encoder filter ]----->[ multiplexer ]
    ///    [                ]----->[                ]      [             ]
    ///
    ///
    ///  option 3: dual encoder filters
    ///    [                ]----->[   video        ]    
    ///    [ capture filter ]      [ encoder filter ]------>[             ]
    ///    [                ]      [                ]       [             ]
    ///    [                ]                               [ multiplexer ]
    ///    [                ]----->[   audio        ]------>[             ]
    ///                            [ encoder filter ]      
    ///                            [                ]
    ///
    ///  option 4: no encoder filter
    ///    [                ]----->[             ]
    ///    [ capture filter ]      [ multiplexer ]
    ///    [                ]----->[             ]
    /// </summary>
    /// <param name="matchPinNames">if set to <c>true</c> the pin names of the multiplexer filter should match the pin names of the encoder filter.</param>
    /// <param name="_graphBuilder">GraphBuilder</param>
    /// <param name="_tuner">Tuner</param>
    /// <param name="_tvAudio">TvAudio</param>
    /// <param name="_crossbar">Crossbar</param>
    /// <param name="_capture">Capture</param>
    /// <returns>true if encoder filters are added, otherwise false</returns>
    private bool AddTvMultiPlexer(bool matchPinNames, IFilterGraph2 _graphBuilder, Tuner _tuner, TvAudio _tvAudio,
                                  Crossbar _crossbar, Capture _capture)
    {
      //Log.Log.WriteFile("analog: AddTvMultiPlexer");
      DsDevice[] devicesHW;
      DsDevice[] devicesSW;
      DsDevice[] devices;
      //get a list of all multiplexers available on this system
      try
      {
        devicesHW = DsDevice.GetDevicesOfCat(FilterCategory.WDMStreamingMultiplexerDevices);
        devicesHW = DeviceSorter.Sort(devicesHW, _tuner.TunerName, _tvAudio.TvAudioName, _crossbar.CrossBarName,
                                      _capture.VideoCaptureName, _capture.AudioCaptureName, _videoEncoderDevice,
                                      _audioEncoderDevice, _multiplexerDevice);
        // also add the SoftWare Multiplexers in case no compatible HardWare multiplexer is found (NVTV cards)
        devicesSW = _tuner.IsNvidiaCard()
                      ? DsDevice.GetDevicesOfCat(FilterCategory.MediaMultiplexerCategory)
                      : new DsDevice[0];

        devices = new DsDevice[devicesHW.Length + devicesSW.Length];
        int nr = 0;
        for (int i = 0; i < devicesHW.Length; ++i)
          devices[nr++] = devicesHW[i];
        for (int i = 0; i < devicesSW.Length; ++i)
          devices[nr++] = devicesSW[i];
      }
      catch (Exception ex)
      {
        Log.Log.WriteFile("analog: AddTvMultiPlexer no multiplexer devices found (Exception) " + ex.Message);
        return false;
      }
      if (devices.Length == 0)
      {
        Log.Log.WriteFile("analog: AddTvMultiPlexer no multiplexer devices found");
        return false;
      }
      //for each multiplexer
      for (int i = 0; i < devices.Length; i++)
      {
        IBaseFilter tmp;
        Log.Log.WriteFile("analog: AddTvMultiPlexer try:{0} {1}", devices[i].Name, i);
        // if multiplexer is in use, we can skip it
        if (DevicesInUse.Instance.IsUsed(devices[i]))
          continue;
        int hr;
        try
        {
          //add multiplexer 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 it to graph, continue with the next multiplexer
          if (tmp != null)
          {
            _graphBuilder.RemoveFilter(tmp);
            Release.ComObject("multiplexer filter", tmp);
          }
          continue;
        }
        // try to connect the multiplexer to encoders/capture devices
        if (ConnectMultiplexer(tmp, matchPinNames, _graphBuilder, _tuner, _capture))
        {
          // succeeded, we're done
          _filterMultiplexer = tmp;
          _multiplexerDevice = devices[i];
          DevicesInUse.Instance.Add(_multiplexerDevice);
          Log.Log.WriteFile("analog: AddTvMultiPlexer succeeded");
          break;
        }
        // unable to connect it, remove the filter and continue with the next one
        _graphBuilder.RemoveFilter(tmp);
        Release.ComObject("multiplexer filter", tmp);
      }
      if (_filterMultiplexer == null)
      {
        Log.Log.WriteFile("analog: no TvMultiPlexer found");
        return false;
      }
      return true;
    }
Exemple #13
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);
        }
Exemple #14
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);
        }
 private void handleInternalNetworkProviderFilter(DsDevice[] devices, IFilterGraph2 graphBuilder,
                                                  Guid networkProviderClsId, DsROTEntry rotEntry)
 {
   IDvbNetworkProvider interfaceNetworkProvider;
   TuningType tuningTypes;
   for (int i = 0; i < devices.Length; i++)
   {
     bool isCablePreferred = false;
     string name = devices[i].Name ?? "unknown";
     name = name.ToLowerInvariant();
     Log.Log.WriteFile("Found card:{0}", name);
     //silicondust work-around for dvb type detection issue. generic provider would always use dvb-t
     if (name.Contains("silicondust hdhomerun tuner"))
     {
       isCablePreferred = CheckHDHomerunCablePrefered(name);
       Log.Log.WriteFile("silicondust hdhomerun detected - prefer cable mode: {0}", isCablePreferred);
     }
     IBaseFilter tmp;
     graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, name, out tmp);
     //Use the Microsoft Network Provider method first but only if available
     IBaseFilter networkDVB = FilterGraphTools.AddFilterFromClsid(graphBuilder, networkProviderClsId,
                                                                  "MediaPortal Network Provider");
     interfaceNetworkProvider = (IDvbNetworkProvider)networkDVB;
     string hash = GetHash(devices[i].DevicePath);
     interfaceNetworkProvider.ConfigureLogging(GetFileName(devices[i].DevicePath), hash, LogLevelOption.Debug);
     if (ConnectFilter(graphBuilder, networkDVB, tmp))
     {
       Log.Log.WriteFile("Detected DVB card:{0}- Hash: {1}", name, hash);
       interfaceNetworkProvider.GetAvailableTuningTypes(out tuningTypes);
       Log.Log.WriteFile("TuningTypes: " + tuningTypes);
       // determine the DVB card supported GUIDs here!
       if ((tuningTypes & TuningType.DvbT) != 0 && !isCablePreferred)
       {
         Log.Log.WriteFile("Detected DVB-T* card:{0}", name);
         TvCardDVBT dvbtCard = new TvCardDVBT(_epgEvents, devices[i]);
         _cards.Add(dvbtCard);
       }
       if ((tuningTypes & TuningType.DvbS) != 0 && !isCablePreferred)
       {
         Log.Log.WriteFile("Detected DVB-S* card:{0}", name);
         TvCardDVBS dvbsCard = new TvCardDVBS(_epgEvents, devices[i]);
         _cards.Add(dvbsCard);
       }
       if ((tuningTypes & TuningType.DvbC) != 0)
       {
         Log.Log.WriteFile("Detected DVB-C* card:{0}", name);
         TvCardDVBC dvbcCard = new TvCardDVBC(_epgEvents, devices[i]);
         _cards.Add(dvbcCard);
       }
       if ((tuningTypes & TuningType.Atsc) != 0 && !isCablePreferred)
       {
         Log.Log.WriteFile("Detected ATSC* card:{0}", name);
         TvCardATSC dvbsCard = new TvCardATSC(_epgEvents, devices[i]);
         _cards.Add(dvbsCard);
       }
     }
     graphBuilder.RemoveFilter(tmp);
     Release.ComObject("tmp filter", tmp);
     graphBuilder.RemoveFilter(networkDVB);
     Release.ComObject("ms provider", networkDVB);
   }
   FilterGraphTools.RemoveAllFilters(graphBuilder);
   rotEntry.Dispose();
   Release.ComObject("graph builder", graphBuilder);
 }
        /// <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);
        }
Exemple #17
0
        /// <summary>
        /// Open a new video feed (either web-cam or video file).
        /// </summary>
        /// <param name="filter">Specifies the web-cam filter to use, or <i>null</i> when opening a video file.</param>
        /// <param name="pb">Specifies the output window, or <i>null</i> when running headless and only receiving snapshots.</param>
        /// <param name="strFile">Specifies the video file to use, or <i>null</i> when opening a web-cam feed.</param>
        /// <param name="vidCap">Optionally specifies the video capabilities to use, or <i>null</i> to ignore and use the default video capabilities.</param>
        /// <returns>The duration (if any) is returned, or 0.</returns>
        /// <remarks>To get the video capabilities see the GetVideoCapatiblities method.</remarks>
        public long Open(Filter filter, PictureBox pb, string strFile, VideoCapability vidCap = null)
        {
            int hr;

            if (filter != null && strFile != null)
            {
                throw new ArgumentException("Both the filter and file are non NULL - only one of these can be used at a time; The filter is used with the web-cam and the file is used with a video file.");
            }

            m_selectedFilter = filter;
            m_graphBuilder   = (IFilterGraph2)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.FilterGraph, true));

            // When using a web-cam, create the moniker for the filter and add the filter to the graph.
            if (strFile == null)
            {
                IMoniker moniker = m_selectedFilter.CreateMoniker();
                m_graphBuilder.AddSourceFilterForMoniker(moniker, null, m_selectedFilter.Name, out m_camFilter);
                Marshal.ReleaseComObject(moniker);
                m_camControl = m_camFilter as IAMCameraControl;

                // Create the capture builder used to build the web-cam filter graph.
                m_captureGraphBuilder = (ICaptureGraphBuilder2)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.CaptureGraphBuilder2, true));
                hr = m_captureGraphBuilder.SetFiltergraph(m_graphBuilder as IGraphBuilder);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Add the web-cam filter to the graph.
                hr = m_graphBuilder.AddFilter(m_camFilter, m_selectedFilter.Name);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Set the desired video capabilities.
                if (vidCap != null)
                {
                    setVideoCapabilities(m_captureGraphBuilder, m_camFilter, vidCap);
                }
            }
            else
            {
                // Build the graph with the video file.
                hr = m_graphBuilder.RenderFile(strFile, null);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                m_mediaSeek = m_graphBuilder as IMediaSeeking;

                if (pb != null)
                {
                    m_videoFrameStep = m_graphBuilder as IVideoFrameStep;
                }
            }

            // Create the sample grabber used to get snapshots.
            m_sampleGrabber  = (ISampleGrabber)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.SampleGrabber, true));
            m_baseGrabFilter = m_sampleGrabber as IBaseFilter;
            m_mediaControl   = m_graphBuilder as IMediaControl;

            // When using a target window, get the video window used with the target output window
            if (pb != null)
            {
                m_mediaEventEx = m_graphBuilder as IMediaEventEx;
                m_videoWindow  = m_graphBuilder as IVideoWindow;
            }
            // Otherwise create the null renderer for no video output is needed (only snapshots).
            else
            {
                m_nullRenderer = (IBaseFilter)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.NullRenderer, true));
            }

            // Add the sample grabber to the filter graph.
            hr = m_graphBuilder.AddFilter(m_baseGrabFilter, "Ds.Lib Grabber");
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // Turn off the sample grabber buffers.
            hr = m_sampleGrabber.SetBufferSamples(false);
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // Turn off the sample grabber one-shot.
            hr = m_sampleGrabber.SetOneShot(false);
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // Turn ON the sample grabber callback where video data is to be received.
            hr = m_sampleGrabber.SetCallback(this, 1);
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // Set the media format used by the sample grabber.
            AMMediaType media = new AMMediaType();

            media.majorType  = MediaType.Video;
            media.subType    = MediaSubType.RGB24;
            media.formatType = FormatType.VideoInfo;

            hr = m_sampleGrabber.SetMediaType(media);
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // Connect the WebCam Filters and Frame Grabber.
            if (m_selectedFilter != null)
            {
                Guid cat;
                Guid med;

                cat = PinCategory.Preview;
                med = MediaType.Video;
                hr  = m_captureGraphBuilder.RenderStream(ref cat, ref med, m_camFilter, null, null);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                cat = PinCategory.Capture;
                med = MediaType.Video;
                hr  = m_captureGraphBuilder.RenderStream(ref cat, ref med, m_camFilter, null, m_baseGrabFilter);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }
            // Connect the Frame Grabber and (optionally the Null Renderer)
            else
            {
                // Get the video decoder and its pins.
                m_videoFilter = Utility.GetFilter(m_graphBuilder as IGraphBuilder, "Video Decoder", false);

                IPin pOutput;
                hr = Utility.GetPin(m_videoFilter, PinDirection.Output, out pOutput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                IPin pInput;
                hr = pOutput.ConnectedTo(out pInput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                PinInfo pinInfo;
                hr = pInput.QueryPinInfo(out pinInfo);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Get the sample grabber pins.
                IPin pGrabInput;
                hr = Utility.GetPin(m_baseGrabFilter, PinDirection.Input, out pGrabInput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                IPin pGrabOutput;
                hr = Utility.GetPin(m_baseGrabFilter, PinDirection.Output, out pGrabOutput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Disconnect the source filter output and the input it is connected to.
                hr = pOutput.Disconnect();
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                hr = pInput.Disconnect();
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Connect the source output to the Grabber input.
                hr = m_graphBuilder.Connect(pOutput, pGrabInput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // When rendering video output, connect the Grabber output to the original downstream input that the source was connected to.
                if (m_nullRenderer == null)
                {
                    hr = m_graphBuilder.Connect(pGrabOutput, pInput);
                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }
                }

                Marshal.ReleaseComObject(pOutput);
                Marshal.ReleaseComObject(pInput);
                Marshal.ReleaseComObject(pGrabInput);
                Marshal.ReleaseComObject(pGrabOutput);
            }

            // Remove sound filters.
            IBaseFilter soundFilter = Utility.GetFilter(m_graphBuilder as IGraphBuilder, "Audio Decoder", false);

            if (soundFilter != null)
            {
                hr = m_graphBuilder.RemoveFilter(soundFilter);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                Marshal.ReleaseComObject(soundFilter);
            }

            soundFilter = Utility.GetFilter(m_graphBuilder as IGraphBuilder, "Sound", false);
            if (soundFilter != null)
            {
                hr = m_graphBuilder.RemoveFilter(soundFilter);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                Marshal.ReleaseComObject(soundFilter);
            }

            // When using a headless (no video rendering) setup, connect the null renderer to the Sample Grabber.
            if (m_nullRenderer != null)
            {
                // Add the null renderer.
                hr = m_graphBuilder.AddFilter(m_nullRenderer, "Null Renderer");
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Get the sample grabber output pin.
                IPin pGrabOutput;
                hr = Utility.GetPin(m_baseGrabFilter, PinDirection.Output, out pGrabOutput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Get the null renderer input pin.
                IPin pInput;
                hr = Utility.GetPin(m_nullRenderer, PinDirection.Input, out pInput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Disconnect the sample grabber pin.
                hr = pGrabOutput.Disconnect();
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Connect the Grabber output to the null renderer.
                hr = m_graphBuilder.Connect(pGrabOutput, pInput);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                Marshal.ReleaseComObject(pInput);
                Marshal.ReleaseComObject(pGrabOutput);

                // Remove the Video Renderer for it is no longer needed.
                IBaseFilter ivideorender = Utility.GetFilter(m_graphBuilder as IGraphBuilder, "Video Renderer");
                if (ivideorender != null)
                {
                    m_graphBuilder.RemoveFilter(ivideorender);
                    Marshal.ReleaseComObject(ivideorender);
                }
            }

            // Get the sample grabber media settings and video header.
            media = new AMMediaType();
            hr    = m_sampleGrabber.GetConnectedMediaType(media);
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            if ((media.formatType != FormatType.VideoInfo &&
                 media.formatType != FormatType.WaveEx &&
                 media.formatType != FormatType.MpegVideo) ||
                media.formatPtr == IntPtr.Zero)
            {
                throw new Exception("Media grabber format is unknown.");
            }

            // Get the video header with frame sizing information.
            m_videoInfoHeader = Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)) as VideoInfoHeader;
            Marshal.FreeCoTaskMem(media.formatPtr);
            media.formatPtr = IntPtr.Zero;

            // If we are rendering video output, setup the video window (which requires a message pump).
            if (m_videoWindow != null)
            {
                // setup the video window
                hr = m_videoWindow.put_Owner(pb.Handle);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                hr = m_videoWindow.put_WindowStyle(WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }


                // resize the window
                hr = m_videoWindow.SetWindowPosition(0, 0, pb.Width, pb.Height);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                hr = m_videoWindow.put_Visible(DsHlp.OATRUE);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Subscribe to the picturebox size changed event.
                pb.SizeChanged += Pb_SizeChanged;
            }


            // start the capturing
            hr = m_mediaControl.Run();
            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // When using a video file, immediately stop at the start.
            if (strFile != null)
            {
                hr = m_mediaControl.Pause();
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            // When using a media file, we need to save the video file's duration.
            if (m_mediaSeek != null)
            {
                hr = m_mediaSeek.GetDuration(out m_lDuration);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            m_bConnected = true;

            return(m_lDuration);
        }
        /// <summary>
        /// Creates the filter by trying to detect it
        /// </summary>
        /// <param name="tvAudio">The tvaudio component</param>
        /// <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>
        /// <param name="capBuilder">The Capture graph builder</param>
        /// <returns>true, if the graph building was successful</returns>
        private bool CreateAutomaticFilterInstance(Graph graph, ICaptureGraphBuilder2 capBuilder, IFilterGraph2 graphBuilder,
                                                   Tuner tuner, Crossbar crossbar, TvAudio tvAudio)
        {
            DsDevice[] devices;
            bool       videoConnected = false;
            bool       audioConnected = false;

            //get a list of all video capture devices
            try
            {
                if (tuner.TunerName == "Adaptec USB TvTuner")
                {
                    Log.Log.WriteFile("analog: Adaptec USB device detected!");
                    devices = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice);
                }
                else
                {
                    devices = DsDevice.GetDevicesOfCat(FilterCategory.AMKSCapture);
                    devices = DeviceSorter.Sort(devices, tuner.TunerName, tvAudio.TvAudioName, crossbar.CrossBarName);
                }
            }
            catch (Exception)
            {
                Log.Log.WriteFile("analog: AddTvCaptureFiler error in allocating devices collection");
                return(false);
            }
            if (devices.Length == 0)
            {
                Log.Log.WriteFile("analog: AddTvCaptureFilter no tvcapture devices found");
                return(false);
            }
            //try each video capture filter
            for (int i = 0; i < devices.Length; i++)
            {
                bool        filterUsed = false;
                IBaseFilter tmp;
                if (_badCaptureDevices.Contains(devices[i].Name))
                {
                    Log.Log.WriteFile("analog: AddTvCaptureFilter bypassing: {0}", devices[i].Name);
                    continue;
                }
                Log.Log.WriteFile("analog: AddTvCaptureFilter try:{0} {1}", devices[i].Name, i);
                // if video capture filter is in use, then we can skip it
                if (DevicesInUse.Instance.IsUsed(devices[i]))
                {
                    continue;
                }
                int hr;
                try
                {
                    // add video capture filter 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)
                {
                    //cannot add video capture filter to graph, try next one
                    if (tmp != null)
                    {
                        graphBuilder.RemoveFilter(tmp);
                        Release.ComObject("TvCaptureFilter", tmp);
                    }
                    continue;
                }

                int destinationIndex;
                // connect crossbar->video capture filter
                if (!videoConnected &&
                    FilterGraphTools.ConnectFilter(graphBuilder, crossbar.VideoOut, tmp, out destinationIndex))
                {
                    _filterVideoCapture = tmp;
                    _videoCaptureDevice = devices[i];
                    if (_audioCaptureDevice != _videoCaptureDevice)
                    {
                        DevicesInUse.Instance.Add(_videoCaptureDevice);
                    }
                    Log.Log.WriteFile("analog: AddTvCaptureFilter connected video to crossbar successfully");
                    graph.Capture.Name    = _videoCaptureDevice.Name;
                    graph.Capture.VideoIn = destinationIndex;
                    videoConnected        = true;
                    filterUsed            = true;
                }
                // crossbar->audio capture filter
                // Many video capture are also the audio capture filter, so we can always try it again
                if (videoConnected && FilterGraphTools.ConnectFilter(graphBuilder, crossbar.AudioOut, tmp, out destinationIndex))
                {
                    _filterAudioCapture = tmp;
                    _audioCaptureDevice = devices[i];
                    if (_audioCaptureDevice != _videoCaptureDevice)
                    {
                        DevicesInUse.Instance.Add(_audioCaptureDevice);
                    }
                    Log.Log.WriteFile("analog: AddTvCaptureFilter connected audio to crossbar successfully");
                    graph.Capture.AudioCaptureName = devices[i].Name;
                    graph.Capture.AudioIn          = destinationIndex;
                    audioConnected = true;
                    filterUsed     = true;
                }
                // _audioCaptureDevice should never be null - avoids null exception crashes with Encoder.cs
                else
                {
                    _audioCaptureDevice = devices[i];
                }

                if (!filterUsed)
                {
                    // cannot connect crossbar->video capture filter, remove filter from graph
                    // cand continue with the next vieo capture filter
                    Log.Log.WriteFile("analog: AddTvCaptureFilter failed to connect to crossbar");
                    graphBuilder.RemoveFilter(tmp);
                    Release.ComObject("capture filter", tmp);
                }
                else
                {
                    i = -1; // Go through the devices again from the start...
                }
                if (videoConnected && audioConnected)
                {
                    break;
                }
            }
            if (_filterVideoCapture != null)
            {
                FindVBIPin(graph);
                CheckCapabilities(graph, capBuilder);
            }
            return(_filterVideoCapture != null);
        }
Exemple #19
0
        public static void AddBDATunerAndDemodulatorToGraph(IFilterGraph2 graphBuilder, IBaseFilter networkProvider, out IBaseFilter tuner, out IBaseFilter capture)
        {
            int hr = 0;

            DsDevice[]            devices;
            ICaptureGraphBuilder2 capBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2();

            capBuilder.SetFiltergraph(graphBuilder);

            try
            {
                tuner   = null;
                capture = null;

                devices = DsDevice.GetDevicesOfCat(FilterCategory.BDASourceFiltersCategory);

                for (int i = 0; i < devices.Length; i++)
                {
                    IBaseFilter tmp;

                    hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
                    DsError.ThrowExceptionForHR(hr);

                    hr = capBuilder.RenderStream(null, null, networkProvider, null, tmp);
                    if (hr == 0)
                    {
                        tuner = tmp;
                        break;
                    }
                    else
                    {
                        hr = graphBuilder.RemoveFilter(tmp);
                        Marshal.ReleaseComObject(tmp);
                    }
                }

                devices = DsDevice.GetDevicesOfCat(FilterCategory.BDAReceiverComponentsCategory);

                for (int i = 0; i < devices.Length; i++)
                {
                    IBaseFilter tmp;

                    hr = graphBuilder.AddSourceFilterForMoniker(devices[i].Mon, null, devices[i].Name, out tmp);
                    DsError.ThrowExceptionForHR(hr);

                    hr = capBuilder.RenderStream(null, null, tuner, null, tmp);
                    if (hr == 0)
                    {
                        capture = tmp;
                        break;
                    }
                    else
                    {
                        hr = graphBuilder.RemoveFilter(tmp);
                        Marshal.ReleaseComObject(tmp);
                    }
                }
            }
            finally
            {
                Marshal.ReleaseComObject(capBuilder);
            }
        }
Exemple #20
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;
 }
Exemple #21
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);
 }
Exemple #22
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;
    }