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