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> /// This method adds the bda network provider filter to the graph /// </summary> protected void AddNetworkProviderFilter(Guid networkProviderClsId) { Log.Log.WriteFile("dvb:AddNetworkProviderFilter"); if (useInternalNetworkProvider) { const string networkProviderName = "MediaPortal Network Provider"; Guid internalNetworkProviderClsId = new Guid("{D7D42E5C-EB36-4aad-933B-B4C419429C98}"); Log.Log.WriteFile("dvb:Add {0}", networkProviderName); _filterNetworkProvider = FilterGraphTools.AddFilterFromClsid(_graphBuilder, internalNetworkProviderClsId, networkProviderName); _interfaceNetworkProvider = (IDvbNetworkProvider)_filterNetworkProvider; string hash = DeviceDetector.GetHash(DevicePath); _interfaceNetworkProvider.ConfigureLogging(DeviceDetector.GetFileName(DevicePath), hash, LogLevelOption.Debug); return; } _isATSC = false; _managedThreadId = System.Threading.Thread.CurrentThread.ManagedThreadId; Log.Log.WriteFile("dvb:AddNetworkProviderFilter"); TvBusinessLayer layer = new TvBusinessLayer(); Card c = layer.GetCardByDevicePath(DevicePath); // generic network provider Guid. Guid genProviderClsId = new Guid("{B2F3A67C-29DA-4C78-8831-091ED509A475}"); // First test if the Generic Network Provider is available (only on MCE 2005 + Update Rollup 2) // only if it is used in db, we need to change it // This check is because, "Genric network provider" is default value in Db // And we need to check if it's even installed. // If not, Then it must be changed automatically, to Network provider // based on Card type. It prevents users to run into problems // If Generic network provider is not available in Os. if (((TvDatabase.DbNetworkProvider)c.netProvider) == TvDatabase.DbNetworkProvider.Generic) { if (!FilterGraphTools.IsThisComObjectInstalled(genProviderClsId)) { // it's not and we have it as default // change it per devtype. if (networkProviderClsId == typeof (DVBTNetworkProvider).GUID) { c.netProvider = (int)TvDatabase.DbNetworkProvider.DVBT; c.Persist(); } else if (networkProviderClsId == typeof (DVBSNetworkProvider).GUID) { c.netProvider = (int)TvDatabase.DbNetworkProvider.DVBS; c.Persist(); } else if (networkProviderClsId == typeof (ATSCNetworkProvider).GUID) { c.netProvider = (int)TvDatabase.DbNetworkProvider.ATSC; c.Persist(); } else if (networkProviderClsId == typeof (DVBCNetworkProvider).GUID) { c.netProvider = (int)TvDatabase.DbNetworkProvider.DVBC; c.Persist(); } } } // Final selecion for Network provider based on user selection. String NetworkProviderName = String.Empty; switch ((TvDatabase.DbNetworkProvider)c.netProvider) { case DbNetworkProvider.DVBT: NetworkProviderName = "DVBT Network Provider"; break; case DbNetworkProvider.DVBS: NetworkProviderName = "DVBS Network Provider"; break; case DbNetworkProvider.DVBC: NetworkProviderName = "DVBC Network Provider"; break; case DbNetworkProvider.ATSC: _isATSC = true; NetworkProviderName = "ATSC Network Provider"; break; case DbNetworkProvider.Generic: NetworkProviderName = "Generic Network Provider"; networkProviderClsId = genProviderClsId; break; default: Log.Log.Error("dvb:This application doesn't support this Tuning Space"); // Tuning Space can also describe Analog TV but this application don't support them throw new TvException("This application doesn't support this Tuning Space"); } Log.Log.WriteFile("dvb:Add {0}", NetworkProviderName); _filterNetworkProvider = FilterGraphTools.AddFilterFromClsid(_graphBuilder, networkProviderClsId, NetworkProviderName); }