/// <summary> /// QueryConnect checks if two Pins can be connected. /// </summary> /// <param name="pin">Pin 1</param> /// <param name="other">Pin 2</param> /// <returns>True if they accept connection</returns> static bool QueryConnect(IPin pin, IPin other) { IEnumMediaTypes enumTypes; int hr = pin.EnumMediaTypes(out enumTypes); if (hr != 0 || enumTypes == null) { return(false); } int count = 0; IntPtr ptrFetched = Marshal.AllocCoTaskMem(4); try { for (; ;) { AMMediaType[] types = new AMMediaType[1]; hr = enumTypes.Next(1, types, ptrFetched); if (hr != 0 || Marshal.ReadInt32(ptrFetched) == 0) { break; } count++; try { if (other.QueryAccept(types[0]) == 0) { return(true); } } finally { FilterGraphTools.FreeAMMediaType(types[0]); } } PinInfo info; PinInfo infoOther; pin.QueryPinInfo(out info); other.QueryPinInfo(out infoOther); ServiceRegistration.Get <ILogger>().Info("Pins {0} and {1} do not accept each other. Tested {2} media types", info.name, infoOther.name, count); FilterGraphTools.FreePinInfo(info); FilterGraphTools.FreePinInfo(infoOther); return(false); } finally { Marshal.FreeCoTaskMem(ptrFetched); } }
/// <summary> /// Enumerates streams from video (audio, subtitles). /// </summary> /// <param name="forceRefresh">Force refresh</param> /// <returns><c>true</c> if information has been changed.</returns> protected virtual bool EnumerateStreams(bool forceRefresh) { if (_graphBuilder == null || !_initialized) { return(false); } StreamInfoHandler audioStreams; StreamInfoHandler subtitleStreams; StreamInfoHandler titleStreams; lock (SyncObj) { audioStreams = _streamInfoAudio; subtitleStreams = _streamInfoSubtitles; titleStreams = _streamInfoTitles; } if (forceRefresh || audioStreams == null || subtitleStreams == null || titleStreams == null) { audioStreams = new StreamInfoHandler(); subtitleStreams = new StreamInfoHandler(); titleStreams = new StreamInfoHandler(); // Release stream selectors ReleaseStreamSelectors(); _streamSelectors = FilterGraphTools.FindFiltersByInterface <IAMStreamSelect>(_graphBuilder); foreach (IAMStreamSelect streamSelector in _streamSelectors) { FilterInfo fi = FilterGraphTools.QueryFilterInfoAndFree(((IBaseFilter)streamSelector)); int streamCount; streamSelector.Count(out streamCount); for (int i = 0; i < streamCount; ++i) { AMMediaType mediaType; AMStreamSelectInfoFlags selectInfoFlags; int groupNumber, lcid; string name; object pppunk, ppobject; streamSelector.Info(i, out mediaType, out selectInfoFlags, out lcid, out groupNumber, out name, out pppunk, out ppobject); // If stream does not contain a LCID, try a lookup from stream name. if (lcid == 0) { lcid = LookupLcidFromName(name); } ServiceRegistration.Get <ILogger>().Debug("Stream {4}|{0}: MajorType {1}; Name {2}; PWDGroup: {3}; LCID: {5}", i, mediaType.majorType, name, groupNumber, fi.achName, lcid); StreamInfo currentStream = new StreamInfo(streamSelector, i, name, lcid); switch ((StreamGroup)groupNumber) { case StreamGroup.Video: break; case StreamGroup.Audio: if (mediaType.majorType == MediaType.AnalogAudio || mediaType.majorType == MediaType.Audio) { String streamName = name.Trim(); String streamAppendix; if (!CodecHandler.MediaSubTypes.TryGetValue(mediaType.subType, out streamAppendix)) { streamAppendix = string.Empty; } // if audio information is available via WaveEx format, query the channel count if (mediaType.formatType == FormatType.WaveEx && mediaType.formatPtr != IntPtr.Zero) { WaveFormatEx waveFormatEx = (WaveFormatEx)Marshal.PtrToStructure(mediaType.formatPtr, typeof(WaveFormatEx)); currentStream.ChannelCount = waveFormatEx.nChannels; streamAppendix = String.Format("{0} {1}ch", streamAppendix, currentStream.ChannelCount); } if (!string.IsNullOrEmpty(streamAppendix)) { currentStream.Name = String.Format("{0} ({1})", streamName, streamAppendix); } audioStreams.AddUnique(currentStream); } break; case StreamGroup.Subtitle: case StreamGroup.DirectVobSubtitle: subtitleStreams.AddUnique(currentStream, true); break; case StreamGroup.MatroskaEdition: // This is a MKV Edition handled by Haali splitter titleStreams.AddUnique(currentStream, true); break; } // Free MediaType and references FilterGraphTools.FreeAMMediaType(mediaType); } } lock (SyncObj) { _streamInfoAudio = audioStreams; _streamInfoSubtitles = subtitleStreams; _streamInfoTitles = titleStreams; } return(true); } return(false); }