/// <summary> /// Get filter's pin. /// </summary> /// /// <param name="filter">Filter to get pin of.</param> /// <param name="dir">Pin's direction.</param> /// <param name="num">Pin's number.</param> /// /// <returns>Returns filter's pin.</returns> /// public static IPin GetPin( IBaseFilter filter, PinDirection dir, int num ) { IPin[] pin = new IPin[1]; IEnumPins pinsEnum = null; // enum filter pins if ( filter.EnumPins( out pinsEnum ) == 0 ) { PinDirection pinDir; int n; // get next pin while ( pinsEnum.Next( 1, pin, out n ) == 0 ) { // query pin`s direction pin[0].QueryDirection( out pinDir ); if ( pinDir == dir ) { if ( num == 0 ) return pin[0]; num--; } Marshal.ReleaseComObject( pin[0] ); pin[0] = null; } } return null; }
public static IPin FindPin(IBaseFilter filter, PinDirection direction, Guid mediaType, Guid pinCategory, string preferredName) { if (Guid.Empty != pinCategory) { int idx = 0; do { IPin pinByCategory = DsFindPin.ByCategory(filter, pinCategory, idx); if (pinByCategory != null) { if (IsMatchingPin(pinByCategory, direction, mediaType)) return PrintInfoAndReturnPin(filter, pinByCategory, direction, mediaType, pinCategory, "found by category"); Marshal.ReleaseComObject(pinByCategory); } else break; idx++; } while (true); } if (!string.IsNullOrEmpty(preferredName)) { IPin pinByName = DsFindPin.ByName(filter, preferredName); if (pinByName != null && IsMatchingPin(pinByName, direction, mediaType)) return PrintInfoAndReturnPin(filter, pinByName, direction, mediaType, pinCategory, "found by name"); Marshal.ReleaseComObject(pinByName); } IEnumPins pinsEnum; IPin[] pins = new IPin[1]; int hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); while (pinsEnum.Next(1, pins, IntPtr.Zero) == 0) { IPin pin = pins[0]; if (pin != null) { if (IsMatchingPin(pin, direction, mediaType)) return PrintInfoAndReturnPin(filter, pin, direction, mediaType, pinCategory, "found by direction and media type"); Marshal.ReleaseComObject(pin); } } return null; }
/// <summary> /// Get filter's pin. /// </summary> /// /// <param name="filter">Filter to get pin of.</param> /// <param name="dir">Pin's direction.</param> /// <param name="num">Pin's number.</param> /// /// <returns>Returns filter's pin.</returns> /// public static IPin GetPin(IBaseFilter filter, PinDirection dir, int num) { IPin[] pin = new IPin[1]; IEnumPins pinsEnum = null; // enum filter pins if (filter.EnumPins(out pinsEnum) == 0) { PinDirection pinDir; int n; try { // get next pin while (pinsEnum.Next(1, pin, out n) == 0) { // query pin`s direction _ = pin[0].QueryDirection(out pinDir); if (pinDir == dir) { if (num == 0) { return(pin[0]); } num--; } Marshal.ReleaseComObject(pin[0]); pin[0] = null; } } finally { Marshal.ReleaseComObject(pinsEnum); } } return(null); }
public static void DisconnectPins(IBaseFilter filter) { int hr = 0; if (filter == null) { throw new ArgumentNullException("filter"); } IEnumPins enumPins; IPin[] pins = new IPin[1]; hr = filter.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); IntPtr fetched = Marshal.AllocCoTaskMem(4); try { while (enumPins.Next(pins.Length, pins, fetched) == 0) { try { hr = pins[0].Disconnect(); DsError.ThrowExceptionForHR(hr); } finally { Marshal.ReleaseComObject(pins[0]); } } } finally { Marshal.FreeCoTaskMem(fetched); Marshal.ReleaseComObject(enumPins); } }
/// <summary> /// Gets a specific pin of a specific filter /// </summary> /// <param name="filter">Filter to retrieve the pin for (defines which object should make this method available)</param> /// <param name="dir">Direction</param> /// <param name="num">Number</param> /// <returns>IPin object or null</returns> public static IPin GetPin(this IBaseFilter filter, PinDirection dir, int num) { // Declare variables IPin[] pin = new IPin[1]; IEnumPins pinsEnum = null; // Enumerator the pins if (filter.EnumPins(out pinsEnum) == 0) { // Get the pin direction PinDirection pinDir; int n = 0;; // Loop the pins while (pinsEnum.Next(1, pin, out n) == 0) { // Query the direction pin[0].QueryDirection(out pinDir); // Is the pin direction correct? if (pinDir == dir) { // Yes, check the pins if (num == 0) { return(pin[0]); } num--; } // Release the pin, this is not the one we are looking for Marshal.ReleaseComObject(pin[0]); pin[0] = null; } } // Not found return(null); }
private IPin FindPin(string pin_name, IBaseFilter filter) { IEnumPins enum_pins; ReturnHR = filter.EnumPins(out enum_pins); IPin[] pin = new IPin[1]; while (enum_pins.Next(1, pin, IntPtr.Zero) == 0) { PinInfo pin_info; pin[0].QueryPinInfo(out pin_info); if (String.Compare(pin_info.name, pin_name) == 0) { DsUtils.FreePinInfo(pin_info); return(pin[0]); } } LogError("Pin not found"); return(null); }
public static IPin ByConnectionStatus(IBaseFilter vSource, PinConnectedStatus vStat, int iIndex) { IEnumPins pins; IPin[] ppPins = new IPin[1]; if (vSource == null) { return(null); } DsError.ThrowExceptionForHR(vSource.EnumPins(out pins)); try { while (pins.Next(1, ppPins, IntPtr.Zero) == 0) { IPin pin2; int hr = ppPins[0].ConnectedTo(out pin2); if (hr != -2147220983) { DsError.ThrowExceptionForHR(hr); Marshal.ReleaseComObject(pin2); } if (((hr == 0) && (vStat == PinConnectedStatus.Connected)) || ((hr == -2147220983) && (vStat == PinConnectedStatus.Unconnected))) { if (iIndex == 0) { return(ppPins[0]); } iIndex--; } Marshal.ReleaseComObject(ppPins[0]); } } finally { Marshal.ReleaseComObject(pins); } return(null); }
public int GetPin(IBaseFilter filter, PinDirection dirrequired, int num, out IPin ppPin) { IEnumPins pins; ppPin = null; int num2 = filter.EnumPins(out pins); if ((num2 >= 0) && (pins != null)) { IPin[] ppPins = new IPin[1]; do { int num3; num2 = pins.Next(1, ppPins, out num3); if ((num2 != 0) || (ppPins[0] == null)) { break; } PinDirection pPinDir = (PinDirection)3; num2 = ppPins[0].QueryDirection(out pPinDir); if ((num2 == 0) && (pPinDir == dirrequired)) { if (num == 0) { ppPin = ppPins[0]; ppPins[0] = null; break; } num--; } Marshal.ReleaseComObject(ppPins[0]); ppPins[0] = null; }while (num2 == 0); Marshal.ReleaseComObject(pins); pins = null; } return(num2); }
public static IPin ByDirection(IBaseFilter vSource, PinDirection vDir, int iIndex) { IPin result = null; IPin[] array = new IPin[1]; if (vSource == null) { return(null); } IEnumPins enumPins; int hr = vSource.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); try { while (enumPins.Next(1, array, IntPtr.Zero) == 0) { PinDirection pinDirection; hr = array[0].QueryDirection(out pinDirection); DsError.ThrowExceptionForHR(hr); if (pinDirection == vDir) { if (iIndex == 0) { result = array[0]; break; } iIndex--; } //Marshal.ReleaseComObject(array[0]); } } finally { //Marshal.ReleaseComObject(enumPins); } return(result); }
public static void DisconnectPins(IBaseFilter filter) { int hr = 0; if (filter == null) { throw new ArgumentNullException("filter"); } IEnumPins enumPins; IPin[] pins = new IPin[1]; hr = filter.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); try { //22 int fetched; //22 while (enumPins.Next(pins.Length, pins, out fetched) == 0) while (enumPins.Next(pins.Length, pins, IntPtr.Zero) == 0) { try { hr = pins[0].Disconnect(); DsError.ThrowExceptionForHR(hr); } finally { Marshal.ReleaseComObject(pins[0]); } } } finally { Marshal.ReleaseComObject(enumPins); } }
protected ArrayList findAudioSources(ICaptureGraphBuilder2 graphBuilder, IBaseFilter deviceFilter) { ArrayList list = new ArrayList(); if (deviceFilter is IAMAudioInputMixer) { IEnumPins pins; int num = deviceFilter.EnumPins(out pins); pins.Reset(); if ((num == 0) && (pins != null)) { IPin[] ppPins = new IPin[1]; do { int num2; num = pins.Next(1, ppPins, out num2); if ((num == 0) && (ppPins[0] != null)) { PinDirection output = PinDirection.Output; num = ppPins[0].QueryDirection(out output); if ((num == 0) && (output == PinDirection.Input)) { AudioSource source = new AudioSource(ppPins[0]); list.Add(source); } ppPins[0] = null; } }while (num == 0); Marshal.ReleaseComObject(pins); pins = null; } } if (list.Count == 1) { list.Clear(); } return(list); }
private IPin GetPin(IBaseFilter filter, Func <PinInfo, bool> pred) { IEnumPins enumPins; var retVal = filter.EnumPins(out enumPins); IPin[] pins = new IPin[1]; int fetched; while ((retVal = enumPins.Next(1, pins, out fetched)) == 0) { if (fetched > 0) { PinInfo info = new PinInfo(); retVal = pins[0].QueryPinInfo(info); if (retVal == 0 && pred(info)) { return(pins[0]); } } } return(null); }
static IPin GetPin(IBaseFilter filter, string pinname) { IEnumPins epins; int hr = filter.EnumPins(out epins); checkHR(hr, "Can't enumerate pins"); IntPtr fetched = Marshal.AllocCoTaskMem(4); IPin[] pins = new IPin[1]; while (epins.Next(1, pins, fetched) == 0) { PinInfo pinfo; pins[0].QueryPinInfo(out pinfo); bool found = (pinfo.name == pinname); DsUtils.FreePinInfo(pinfo); if (found) { return(pins[0]); } } checkHR(-1, "Pin not found"); return(null); }
public static bool DisconnectAllPins(IGraphBuilder graphBuilder, IBaseFilter filter) { IEnumPins pinEnum; int hr = filter.EnumPins(out pinEnum); if (hr != 0 || pinEnum == null) { return false; } FilterInfo info; filter.QueryFilterInfo(out info); Marshal.ReleaseComObject(info.pGraph); bool allDisconnected = true; for (; ; ) { IPin[] pins = new IPin[1]; IntPtr fetched = IntPtr.Zero; hr = pinEnum.Next(1, pins, fetched); if (hr != 0 || fetched == IntPtr.Zero) { break; } PinInfo pinInfo; pins[0].QueryPinInfo(out pinInfo); DsUtils.FreePinInfo(pinInfo); if (pinInfo.dir == PinDirection.Output) { if (!DisconnectPin(graphBuilder, pins[0])) { allDisconnected = false; } } Marshal.ReleaseComObject(pins[0]); } Marshal.ReleaseComObject(pinEnum); return allDisconnected; }
protected void removeDownstream(IBaseFilter filter, bool removeFirstFilter) { IEnumPins pins; int num = filter.EnumPins(out pins); pins.Reset(); if ((num == 0) && (pins != null)) { IPin[] ppPins = new IPin[1]; do { int num2; num = pins.Next(1, ppPins, out num2); if ((num == 0) && (ppPins[0] != null)) { IPin ppPin = null; ppPins[0].ConnectedTo(out ppPin); if (ppPin != null) { PinInfo pInfo = new PinInfo(); num = ppPin.QueryPinInfo(out pInfo); if ((num == 0) && (pInfo.dir == PinDirection.Input)) { this.removeDownstream(pInfo.filter, true); this.graphBuilder.Disconnect(ppPin); this.graphBuilder.Disconnect(ppPins[0]); } Marshal.ReleaseComObject(pInfo.filter); Marshal.ReleaseComObject(ppPin); } Marshal.ReleaseComObject(ppPins[0]); } }while (num == 0); Marshal.ReleaseComObject(pins); pins = null; } }
public static List <PinInfo2> GetPins(IBaseFilter filter) { List <PinInfo2> pins = new List <PinInfo2>(); IPin[] pina = new IPin[1]; IEnumPins pinsEnum = null; // enum filter pins if (filter.EnumPins(out pinsEnum) == 0) { PinDirection pinDir; int n; try { // get next pin while (pinsEnum.Next(1, pina, out n) == 0) { // query pin's direction pina[0].QueryDirection(out pinDir); PinInfo pinInfo; pina[0].QueryPinInfo(out pinInfo); PinInfo2 pinInfo2; pinInfo2.Pin = pina[0]; pinInfo2.PinInfo = pinInfo; pins.Add(pinInfo2); } } finally { Marshal.ReleaseComObject(pinsEnum); } } return(pins); }
public static IPin GetPin(this IBaseFilter filter, PinDirection dir, int num) { IPin[] pin = new IPin[1]; IEnumPins pinsEnum = null; try { if (filter.EnumPins(out pinsEnum) == 0) { PinDirection pinDir; int n = 0; while (pinsEnum.Next(1, pin, out n) == 0) { pin[0].QueryDirection(out pinDir); if (pinDir == dir) { if (num == 0) { return(pin[0]); } num--; } Marshal.ReleaseComObject(pin[0]); pin[0] = null; } } } catch (NullReferenceException exNull) { } return(null); }
protected IPin GetUnconnectedPin(IBaseFilter filter, PinDirection direction) { IPin destPin = null; IEnumPins iEnum; var pins = new IPin[1]; var hr = filter.EnumPins(out iEnum); Marshal.ThrowExceptionForHR(hr); var fetched = Marshal.AllocCoTaskMem(4); hr = iEnum.Next(1, pins, fetched); Marshal.ThrowExceptionForHR(hr); while (Marshal.ReadInt32(fetched) == 1) { PinDirection pinDir; IPin pPin; destPin = pins[0]; hr = destPin.QueryDirection(out pinDir); Marshal.ThrowExceptionForHR(hr); PinInfo info; destPin.QueryPinInfo(out info); //var name = info.name; destPin.ConnectedTo(out pPin); if (pPin == null && pinDir == direction) break; hr = iEnum.Next(1, pins, fetched); Marshal.ThrowExceptionForHR(hr); } Marshal.FreeCoTaskMem(fetched); return destPin; }
public IPin GetPin(IBaseFilter filter, string pinname) { IEnumPins epins; if (filter != null) { int hr = filter.EnumPins(out epins); IntPtr fetched = Marshal.AllocCoTaskMem(4); IPin[] pins = new IPin[1]; while (epins.Next(1, pins, fetched) == 0) { PinInfo pinfo; pins[0].QueryPinInfo(out pinfo); bool found = (pinfo.name == pinname); DsUtils.FreePinInfo(pinfo); if (found) { return(pins[0]); } } } return(null); }
public static IEnumerator <WavFormatInfo> EnumerateFormatsForDirection(IBaseFilter filter, PinDirection direction) { if (filter == null) { throw new ArgumentNullException("filter"); } int hr; IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); if (pinsEnum == null) { throw new InvalidOperationException("pinsEnum is null"); } IPin[] pins = new IPin[1]; while (true) { try { int pcFetched; hr = pinsEnum.Next(pins.Length, pins, out pcFetched); DsError.ThrowExceptionForHR(hr); if (pcFetched == 1) { // we have something IPin pin = pins[0]; string queryId; hr = pin.QueryId(out queryId); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); if (pinInfo.dir != direction) { continue; } IEnumMediaTypes mediaTypesEnum = null; try { hr = pin.EnumMediaTypes(out mediaTypesEnum); DsError.ThrowExceptionForHR(hr); AMMediaType[] mediaTypes = new AMMediaType[1]; int mtFetched; while (true) { hr = mediaTypesEnum.Next(1, mediaTypes, out mtFetched); DsError.ThrowExceptionForHR(hr); if (mtFetched == 1) { if (mediaTypes[0].formatType == FormatType.WaveEx) { yield return(new WavFormatInfo(mediaTypes[0])); } } else { break; } } } finally { if (mediaTypesEnum != null) { Marshal.ReleaseComObject(mediaTypesEnum); } } } else { break; } } finally { if (pins[0] != null) { Marshal.ReleaseComObject(pins[0]); } pins[0] = null; } } } finally { if (pinsEnum != null) { Marshal.ReleaseComObject(pinsEnum); } } }
/// <summary> /// This filter has the input pin specified. /// </summary> /// <param name="thisFilter"></param> /// <param name="inputPin"></param> /// <returns></returns> private bool FilterHasInputPin(IBaseFilter thisFilter, IPin inputPin) { if (inputPin == null) return false; IEnumPins enumPins; thisFilter.EnumPins(out enumPins); IPin p; uint fetched; enumPins.Next(1, out p, out fetched); while (fetched == 1) { _PinDirection pinDir; p.QueryDirection(out pinDir); if (pinDir == _PinDirection.PINDIR_INPUT) { if (p.Equals(inputPin)) { return true; } } enumPins.Next(1, out p, out fetched); } return false; }
public static string DumpFilterInfo(IBaseFilter filter) { StringBuilder sb = new StringBuilder(); int hr; sb.AppendLine(">>>>>>> BaseFilter info dump BEGIN"); { Guid guid; hr = filter.GetClassID(out guid); if (0 == hr) { sb.AppendLine("ClassID: " + guid.ToString()); } else { sb.AppendLine("ClassID: " + GetErrorText(hr)); } } { string vendorInfo = null; hr = filter.QueryVendorInfo(out vendorInfo); if (0 == hr) { sb.AppendLine(string.Format("VendorInfo: {0}", vendorInfo)); } else { sb.AppendLine("VendorInfo: " + GetErrorText(hr)); } } { FilterInfo fi; hr = filter.QueryFilterInfo(out fi); if (0 == hr) { sb.AppendLine(string.Format("FilterInfo achName: {0}", fi.achName)); } else { sb.AppendLine("FilterInfo achName: " + GetErrorText(hr)); } } IFileSourceFilter fileSourceFilter = filter as IFileSourceFilter; if (fileSourceFilter != null) { string fileName; AMMediaType mt = new AMMediaType(); fileSourceFilter.GetCurFile(out fileName, mt); DsUtils.FreeAMMediaType(mt); sb.AppendLine("IFileSourceFilter CurFile: " + fileName); } // Pins info { IEnumPins enumPins = null; IPin[] pins = new IPin[1] { null }; try { hr = filter.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); while (enumPins.Next(1, pins, IntPtr.Zero) == 0) { sb.AppendLine(DumpPinInfo(pins[0])); Util.ReleaseComObject(ref pins[0]); } } finally { Marshal.ReleaseComObject(enumPins); } } sb.AppendLine(">>>>>>> BaseFilter info dump END"); return(sb.ToString()); }
public static IPin FindPinForMajorType(IBaseFilter filter, PinDirection direction, Guid majorType) { if (filter == null) { throw new ArgumentNullException("filter"); } int hr = 0; IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); var pins = new IPin[1]; int numberFetched = 1; while (numberFetched > 0) { IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(1, pins, pcFetched); DsError.ThrowExceptionForHR(hr); numberFetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (numberFetched > 0) { PinDirection currentPinDirection; hr = pins[0].QueryDirection(out currentPinDirection); DsError.ThrowExceptionForHR(hr); if (currentPinDirection != direction) { continue; } IEnumMediaTypes mediaTypesEnum = null; try { var mediaTypes = new AMMediaType[1]; pins[0].EnumMediaTypes(out mediaTypesEnum); int numberFetched2 = 1; while (numberFetched2 > 0) { IntPtr fetched2 = IntPtr.Zero; try { hr = mediaTypesEnum.Next(1, mediaTypes, fetched2); DsError.ThrowExceptionForHR(hr); numberFetched2 = Marshal.ReadInt32(fetched2); } finally { Marshal.FreeCoTaskMem(fetched2); } if (numberFetched2 > 0) { if (mediaTypes[0].majorType == majorType) { // success, return the pin return(pins[0]); } } Marshal.ReleaseComObject(pins[0]); } } finally { if (mediaTypesEnum != null) { Marshal.ReleaseComObject(mediaTypesEnum); } } } } } finally { if (pinsEnum != null) { Marshal.ReleaseComObject(pinsEnum); } } return(null); }
public static IList <PinQueryInfo> EnumeratePins(IBaseFilter filter) { if (filter == null) { throw new ArgumentNullException("filter"); } int hr = 0; var pinsInfo = new List <PinQueryInfo>(); IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); if (pinsEnum == null) { throw new InvalidOperationException("pinsEnum is null"); } var pins = new IPin[1]; while (true) { try { int fetched = 0; IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(pins.Length, pins, pcFetched); DsError.ThrowExceptionForHR(hr); fetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (fetched == 1) { // we have something IPin pin = pins[0]; string queryId; hr = pin.QueryId(out queryId); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); pinsInfo.Add(new PinQueryInfo(pinInfo.dir, pinInfo.name, queryId)); } else { break; } } finally { if (pins[0] != null) { Marshal.ReleaseComObject(pins[0]); } pins[0] = null; } } } finally { if (pinsEnum != null) { Marshal.ReleaseComObject(pinsEnum); } } return(pinsInfo); }
static IPin FindPinByDirection(IBaseFilter filter, PinDirection direction) { IPin destPin = null; IEnumPins iEnum; int hr; IPin[] pins = new IPin[1]; hr = filter.EnumPins(out iEnum); DsError.ThrowExceptionForHR(hr); if (iEnum == null) throw new InvalidOperationException("iEnum is null"); IntPtr fetched = Marshal.AllocCoTaskMem(4); hr = iEnum.Next(1, pins, fetched); DsError.ThrowExceptionForHR(hr); while (Marshal.ReadInt32(fetched) == 1) { PinDirection pinDir; IPin pPin; destPin = pins[0]; hr = destPin.QueryDirection(out pinDir); DsError.ThrowExceptionForHR(hr); destPin.ConnectedTo(out pPin); if (pPin == null && pinDir == direction) break; if (pPin != null) Marshal.ReleaseComObject(pPin); hr = iEnum.Next(1, pins, fetched); DsError.ThrowExceptionForHR(hr); } Marshal.FreeCoTaskMem(fetched); return destPin; }
/// <summary> /// Removes all filters downstream from a filter from the graph. /// This is called only by derenderGraph() to remove everything /// from the graph except the devices and compressors. The parameter /// "removeFirstFilter" is used to keep a compressor (that should /// be immediately downstream of the device) if one is begin used. /// </summary> private void removeDownstream( IBaseFilter filter, bool removeFirstFilter ) { if (filter == null) return; // Get a pin enumerator off the filter IEnumPins pinEnum; int hr = filter.EnumPins( out pinEnum ); pinEnum.Reset(); if( (hr == 0) && (pinEnum != null) ) { // Loop through each pin IPin[] pins = new IPin[1]; IntPtr f = IntPtr.Zero; do { // Get the next pin hr = pinEnum.Next(1, pins, f); if( (hr == 0) && (pins[0] != null) ) { // Get the pin it is connected to IPin pinTo = null; pins[0].ConnectedTo( out pinTo ); if ( pinTo != null ) { // Is this an input pin? PinInfo info = new PinInfo(); hr = pinTo.QueryPinInfo( out info ); if( (hr == 0) && (info.dir == (PinDirection.Input)) ) { // Recurse down this branch removeDownstream( info.filter, true ); // Disconnect graphBuilder.Disconnect( pinTo ); graphBuilder.Disconnect( pins[0] ); // Remove this filter // but don't remove the video or audio compressors // if ( ( info.filter != videoCompressorFilter ) && // ( info.filter != audioCompressorFilter ) ) graphBuilder.RemoveFilter( info.filter ); } Marshal.ReleaseComObject( info.filter ); Marshal.ReleaseComObject( pinTo ); } Marshal.ReleaseComObject( pins[0] ); } } while( hr == 0 ); Marshal.ReleaseComObject( pinEnum ); pinEnum = null; } }
/* * TIVO Files Pin Mapping (pin name between ||) (NOTE: XXXX changes from each machine and AC3 changes if the audio codec changes) * Audio -> Source Pin |Output| -> MainConcept MPEG DeMultiplexer |Input| |AC3 (PID XXXX @ Prog# 1)| -> Dump |Input| * Video -> Source Pin |Output| -> MainConcept MPEG DeMultiplexer |Input| |Video (PID XXXX @ Prog# 1)| -> Dump |Input| */ public void BuildGraph() { int hr; IntPtr fetched = IntPtr.Zero; IntPtr fetched2 = IntPtr.Zero; IEnumPins FilterPins; IPin[] pins = new IPin[1]; string PinID; // TiVO Directshow filters are only accessible through userspace otherwise decryption fails, so if we are running the engine as a service (instead of command line) we should prompt the user if ((_Ext == "tivo") && GlobalDefs.IsEngineRunningAsService) { _jobLog.WriteEntry(this, "You need to start MCEBuddy engine as a Command line program. TiVO Desktop Directshow decryption filters do not work with a Windows Service.", Log.LogEntryType.Error); } // Create the source filter for dvrms or wtv or TIVO (will automatically connect to TIVODecryptorTag in source itself) _jobLog.WriteEntry(this, "Loading file using DirectShow source filter", Log.LogEntryType.Debug); hr = _gb.AddSourceFilter(_SourceFile, "Source Filter", out _SourceF); checkHR(hr); // If this is a TIVO while, while the source filter automatically decrypts the inputs we need to connect the MPEG demultiplexer to get the audio and video output pins if (_Ext == "tivo") { IPin PinOut, PinIn; IntPtr ptr; PinInfo demuxPinInfo; List <IBaseFilter> filterList = new List <IBaseFilter>(); // Check if the source filter is a TiVO source filter (otherwise sometimes it tries to use the normal source filter which will fail since the stream in encrypted) string vendorInfo; FilterInfo filterInfo; _SourceF.QueryFilterInfo(out filterInfo); _SourceF.QueryVendorInfo(out vendorInfo); _jobLog.WriteEntry(this, "TiVO Source filter loaded by Directshow -> " + filterInfo.achName + " (" + vendorInfo + ")", Log.LogEntryType.Debug); if (vendorInfo == null || !vendorInfo.ToLower().Contains("tivo")) { string exception = ""; // Check if you are running 64Bit MCEBuddy, TiVO needs 32bit MCEBuddy since TiVO directshow dll are 32bit and can only be loaded by 32bit processes if (IntPtr.Size == 8) { exception += "You need to run 32bit MCEBuddy, TiVO Directshow fiters cannot be accessed by a 64bit program."; } else { exception += "TiVO Desktop installation not detected by Windows DirectShow."; } throw new Exception(exception); // Get out of here and let the parent know something is wrong } hr = _SourceF.FindPin("Output", out PinOut); // Get the Source filter pinOut |Output| checkHR(hr); // When TIVO desktop is installed, Render automatically builds the filter graph with the necessary demuxing filters - we cannot manually add the MainConcept demux filter since the class isn't registered but somehow Render is able to find it and load it (along with other redundant filters like DTV, audio etc which we need to remove) _jobLog.WriteEntry(this, "DirectShow building TiVO filter chain", Log.LogEntryType.Debug); hr = _gb.Render(PinOut); checkHR(hr); hr = PinOut.ConnectedTo(out ptr); // Find out which input Pin (Mainconcept Demux filter) the output of the Source Filter is connected to checkHR(hr); PinIn = (IPin)Marshal.GetObjectForIUnknown(ptr); hr = PinIn.QueryPinInfo(out demuxPinInfo); // Get the mainconcept demux filter from the pin checkHR(hr); demuxPinInfo.filter.QueryFilterInfo(out filterInfo); demuxPinInfo.filter.QueryVendorInfo(out vendorInfo); _jobLog.WriteEntry(this, "Checking downstream TiVO filter chain starting with TiVO Demux filter -> " + filterInfo.achName + " (" + vendorInfo + ")", Log.LogEntryType.Debug); if (!GetFilterChain(demuxPinInfo.filter, PinDirection.Output, filterList)) // Get the list of all downstreams (redudant) filters (like DTV, Audio, video render etc) from the demux filter that were added by the automatic Render function above (check if there are no downstream filters, then TIVO desktop is not installed) { throw new Exception("Unable to get TIVO filter chain"); } // Now remove all the filters in the chain downstream after the demux filter from the graph builder (we dont' need them, we will add out own filters later) _jobLog.WriteEntry(this, "Removing redundant filters from TiVO filter chain", Log.LogEntryType.Debug); foreach (IBaseFilter filter in filterList) { filter.QueryFilterInfo(out filterInfo); filter.QueryVendorInfo(out vendorInfo); _jobLog.WriteEntry(this, "Removing filter -> " + filterInfo.achName + " (" + vendorInfo + ")", Log.LogEntryType.Debug); _gb.RemoveFilter(filter); Marshal.FinalReleaseComObject(filter); // Release the COM object } // Now the TIVO MainConcept Demux Filter is our new "Source" filter _SourceF = demuxPinInfo.filter; } // TODO: We need to find a way to insert a filter which can allow us to select audio streams (e.g. LAV filter, currently it only allows us access to the default audio stream and not multiple audio streams) // Cycle through pins, connecting as appropriate hr = _SourceF.EnumPins(out FilterPins); checkHR(hr); while (FilterPins.Next(pins.Length, pins, fetched) == 0) { IntPtr ptypes = Marshal.AllocCoTaskMem(Marshal.SizeOf(typeof(IntPtr))); AMMediaType mtypes; IEnumMediaTypes enummtypes; IntPtr ptrEnum; pins[0].EnumMediaTypes(out ptrEnum); enummtypes = (IEnumMediaTypes)Marshal.GetObjectForIUnknown(ptrEnum); while (enummtypes.Next(1, ptypes, fetched2) == 0) { /* Extract Audio, Video or Subtitle streams -> References: * http://nate.deepcreek.org.au/svn/DigitalWatch/trunk/bin/MediaTypes.txt * http://msdn.microsoft.com/en-us/library/ms932033.aspx * https://sourceforge.net/p/tsubget/home/Dumping%20a%20Stream/ * http://msdn.microsoft.com/en-us/library/windows/desktop/dd695343(v=vs.85).aspx * http://msdn.microsoft.com/en-us/library/windows/desktop/dd390660(v=vs.85).aspx * http://msdn.microsoft.com/en-us/library/windows/desktop/dd407354(v=vs.85).aspx * http://whrl.pl/RcRv5p (extracting Teletext from WTV/DVRMS) */ IntPtr ptrStructure = Marshal.ReadIntPtr(ptypes); mtypes = (AMMediaType)Marshal.PtrToStructure(ptrStructure, typeof(AMMediaType)); if ((mtypes.majorType == MediaType.Video) || (mtypes.majorType == MediaType.Audio) || (mtypes.majorType == MediaType.Mpeg2PES) || (mtypes.majorType == MediaType.Stream) || (mtypes.majorType == MediaType.AuxLine21Data) || (mtypes.majorType == MediaType.VBI) || (mtypes.majorType == MediaType.MSTVCaption) || (mtypes.majorType == MediaType.DTVCCData) || (mtypes.majorType == MediaType.Mpeg2Sections && mtypes.subType == MediaSubType.None && mtypes.formatType == FormatType.None)) { string DumpFileName = ""; if ((mtypes.majorType == MediaType.Video) && ((_extractMediaType & ExtractMediaType.Video) != 0)) // Video { DumpFileName = Path.Combine(_workPath, Path.GetFileNameWithoutExtension(_SourceFile) + "_VIDEO"); _VideoPart = DumpFileName; _jobLog.WriteEntry(this, "Found Video stream, extracting -> " + DumpFileName, Log.LogEntryType.Debug); } else if (((mtypes.majorType == MediaType.Audio) || // Audio types https://msdn.microsoft.com/en-us/library/windows/desktop/dd390676(v=vs.85).aspx ((mtypes.majorType == MediaType.Mpeg2PES) && ((mtypes.subType == MediaSubType.DolbyAC3) || (mtypes.subType == MediaSubType.DTS) || (mtypes.subType == MediaSubType.DvdLPCMAudio) || (mtypes.subType == MediaSubType.Mpeg2Audio))) || ((mtypes.majorType == MediaType.Stream) && ((mtypes.subType == MediaSubType.DolbyAC3) || (mtypes.subType == MediaSubType.MPEG1Audio) || (mtypes.subType == MediaSubType.Mpeg2Audio) || (mtypes.subType == MediaSubType.DolbyDDPlus) || (mtypes.subType == MediaSubType.MpegADTS_AAC) || (mtypes.subType == MediaSubType.MpegLOAS))) ) && ((_extractMediaType & ExtractMediaType.Audio) != 0)) { DumpFileName = Path.Combine(_workPath, Path.GetFileNameWithoutExtension(_SourceFile) + "_AUDIO" + AudioParts.Count.ToString()); _AudioParts.Add(DumpFileName); _jobLog.WriteEntry(this, "Found Audio stream, extracting -> " + DumpFileName, Log.LogEntryType.Debug); } else if ((_extractMediaType & ExtractMediaType.Subtitle) != 0)// Subtitles { DumpFileName = Path.Combine(_workPath, Path.GetFileNameWithoutExtension(_SourceFile) + "_SUBTITLE" + SubtitleParts.Count.ToString()); SubtitleParts.Add(DumpFileName); _jobLog.WriteEntry(this, "Found Subtitle stream, extracting -> " + DumpFileName, Log.LogEntryType.Debug); } if (!String.IsNullOrWhiteSpace(DumpFileName)) // If we are asked to extract something { hr = pins[0].QueryId(out PinID); ConnectDecryptedDump(PinID, DumpFileName); } } else { // Debug - looking for more subtitle types (very poorly documented by Microsoft) Guid type = mtypes.majorType; Guid subtype = mtypes.subType; Guid formattyype = mtypes.formatType; } } Marshal.FreeCoTaskMem(ptypes); // Free up the memory } }
public static IEnumerator<WavFormatInfo> EnumerateFormatsForDirection(IBaseFilter filter, PinDirection direction) { if (filter == null) throw new ArgumentNullException("filter"); IEnumPins pinsEnum = null; try { int hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); if (pinsEnum == null) throw new InvalidOperationException("pinsEnum is null"); var pins = new IPin[1]; while (true) { try { int fetched = 0; IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(pins.Length, pins, pcFetched); DsError.ThrowExceptionForHR(hr); fetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (fetched == 1) { // we have something IPin pin = pins[0]; string queryId; hr = pin.QueryId(out queryId); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); if (pinInfo.dir != direction) continue; IEnumMediaTypes mediaTypesEnum = null; try { hr = pin.EnumMediaTypes(out mediaTypesEnum); DsError.ThrowExceptionForHR(hr); var mediaTypes = new AMMediaType[1]; while (true) { IntPtr mtFetched = Marshal.AllocCoTaskMem(4); try { hr = mediaTypesEnum.Next(1, mediaTypes, mtFetched); DsError.ThrowExceptionForHR(hr); fetched = Marshal.ReadInt32(mtFetched); } finally { Marshal.FreeCoTaskMem(mtFetched); } if (fetched == 1) { if (mediaTypes[0].formatType == FormatType.WaveEx) { yield return new WavFormatInfo(mediaTypes[0]); } } else { break; } } } finally { if (mediaTypesEnum != null) Marshal.ReleaseComObject(mediaTypesEnum); } } else { break; } } finally { if (pins[0] != null) Marshal.ReleaseComObject(pins[0]); pins[0] = null; } } } finally { if (pinsEnum != null) Marshal.ReleaseComObject(pinsEnum); } }
public static void AddPreferredFilters(IGraphBuilder graphBuilder, IBaseFilter sourceFilter) { using (Settings xmlreader = new MPSettings()) { bool autodecodersettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false); if (!autodecodersettings) // the user has not chosen automatic graph building by merits { // bool vc1ICodec,vc1Codec,xvidCodec = false; - will come later bool aacCodec = false; bool h264Codec = false; // check the output pins of the splitter for known media types IEnumPins pinEnum = null; if (sourceFilter.EnumPins(out pinEnum) == 0) { int fetched = 0; IPin[] pins = new IPin[1]; while (pinEnum.Next(1, pins, out fetched) == 0 && fetched > 0) { IPin pin = pins[0]; PinDirection pinDirection; if (pin.QueryDirection(out pinDirection) == 0 && pinDirection == PinDirection.Output) { IEnumMediaTypes enumMediaTypesVideo = null; if (pin.EnumMediaTypes(out enumMediaTypesVideo) == 0) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; while (enumMediaTypesVideo.Next(1, mediaTypes, out typesFetched) == 0 && typesFetched > 0) { if (mediaTypes[0].majorType == MediaType.Video && (mediaTypes[0].subType == MediaSubType.H264 || mediaTypes[0].subType == MEDIASUBTYPE_AVC1)) { Logger.Instance.Info("found H264 video on output pin"); h264Codec = true; } else if (mediaTypes[0].majorType == MediaType.Audio && mediaTypes[0].subType == MediaSubType.LATMAAC) { Logger.Instance.Info("found AAC audio on output pin"); aacCodec = true; } } DirectShowUtil.ReleaseComObject(enumMediaTypesVideo); } } DirectShowUtil.ReleaseComObject(pin); } DirectShowUtil.ReleaseComObject(pinEnum); } // add filters for found media types to the graph as configured in MP if (h264Codec) { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "h264videocodec", ""))); } else { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""))); } if (aacCodec) { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", ""))); } else { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""))); } } } }
private void RenderPins(IBaseFilter streamBuffer, ICaptureGraphBuilder2 icgb2) { int hr; IEnumPins iep; hr = streamBuffer.EnumPins(out iep); DsError.ThrowExceptionForHR(hr); try { //hr = icgb2.RenderStream(null, null, pPin[0], null, null); #if true IPin[] pPin = new IPin[1]; // Walk each pin of the stream buffer source for ( hr = iep.Next(1, pPin, IntPtr.Zero); hr == 0; hr = iep.Next(1, pPin, IntPtr.Zero) ) { try { AMMediaType[] amt = new AMMediaType[1]; IEnumMediaTypes pEnum; hr = pPin[0].EnumMediaTypes(out pEnum); DsError.ThrowExceptionForHR(hr); try { // Grab the first media type hr = pEnum.Next(1, amt, IntPtr.Zero); DsError.ThrowExceptionForHR(hr); try { // use the media type to render the stream hr = icgb2.RenderStream(null, amt[0].majorType, pPin[0], null, null); DsError.ThrowExceptionForHR(hr); } finally { DsUtils.FreeAMMediaType(amt[0]); } } finally { Marshal.ReleaseComObject(pEnum); } } finally { Marshal.ReleaseComObject(pPin[0]); } } } finally { Marshal.ReleaseComObject(iep); } #endif }
/// <summary> /// Scans a filter's pins looking for a pin with the specified name /// </summary> /// <param name="vSource">The filter to scan</param> /// <param name="vPinName">The pin name to find</param> /// <returns>The matching pin, or null if not found</returns> public static IPin ByName(IBaseFilter vSource, string vPinName) { int hr; IEnumPins ppEnum; PinInfo ppinfo; IPin pRet = null; IPin[] pPins = new IPin[1]; if (vSource == null) { return null; } // Get the pin enumerator hr = vSource.EnumPins(out ppEnum); DsError.ThrowExceptionForHR(hr); try { // Walk the pins looking for a match while (ppEnum.Next(1, pPins, IntPtr.Zero) == 0) { // Read the info hr = pPins[0].QueryPinInfo(out ppinfo); DsError.ThrowExceptionForHR(hr); // Is it the right name? if (ppinfo.name == vPinName) { DsUtils.FreePinInfo(ppinfo); pRet = pPins[0]; break; } Marshal.ReleaseComObject(pPins[0]); DsUtils.FreePinInfo(ppinfo); } } finally { Marshal.ReleaseComObject(ppEnum); } return pRet; }
private IPin FindPin(IBaseFilter filter, PinDirection direction, Guid mediaType, string preferredName) { if (!string.IsNullOrEmpty(preferredName)) { IPin pinByName = DsFindPin.ByName(filter, preferredName); if (IsMatchingPin(pinByName, direction, mediaType)) return pinByName; Marshal.ReleaseComObject(pinByName); } IEnumPins pinsEnum; IPin[] pins = new IPin[1]; int hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); while (pinsEnum.Next(1, pins, IntPtr.Zero) == 0) { IPin pin = pins[0]; if (pin != null) { if (IsMatchingPin(pin, direction, mediaType)) return pin; Marshal.ReleaseComObject(pin); } } return null; }
protected virtual void ConnectAllOutputFiltersFrom(IBaseFilter fromFilter, IFilterGraph2 graph) { // Get the pin enumerator IEnumPins ppEnum; int hr = fromFilter.EnumPins(out ppEnum); DsError.ThrowExceptionForHR(hr); try { // Walk the pins looking for a match IPin[] pPins = new IPin[1]; //22 int lFetched; //22 while ((ppEnum.Next(1, pPins, out lFetched) >= 0) && (lFetched == 1)) while (ppEnum.Next(1, pPins, IntPtr.Zero) >= 0) { // Read the direction PinDirection ppindir; hr = pPins[0].QueryDirection(out ppindir); DsError.ThrowExceptionForHR(hr); // Is it the right direction? if (ppindir == PinDirection.Output) { if (pPins[0] != null) { hr = graph.Render(pPins[0]); //DsError.ThrowExceptionForHR(hr); } } Marshal.ReleaseComObject(pPins[0]); } } finally { Marshal.ReleaseComObject(ppEnum); } }
/// <summary> /// Scans a filter's pins looking for a pin in the specified direction /// </summary> /// <param name="vSource">The filter to scan</param> /// <param name="vDir">The direction to find</param> /// <param name="iIndex">Zero based index (ie 2 will return the third pin in the specified direction)</param> /// <returns>The matching pin, or null if not found</returns> public static IPin ByDirection(IBaseFilter vSource, PinDirection vDir, int iIndex) { int hr; IEnumPins ppEnum; PinDirection ppindir; IPin pRet = null; IPin[] pPins = new IPin[1]; if (vSource == null) { return null; } // Get the pin enumerator hr = vSource.EnumPins(out ppEnum); DsError.ThrowExceptionForHR(hr); try { // Walk the pins looking for a match while (ppEnum.Next(1, pPins, IntPtr.Zero) == 0) { // Read the direction hr = pPins[0].QueryDirection(out ppindir); DsError.ThrowExceptionForHR(hr); // Is it the right direction? if (ppindir == vDir) { // Is is the right index? if (iIndex == 0) { pRet = pPins[0]; break; } iIndex--; } Marshal.ReleaseComObject(pPins[0]); } } finally { Marshal.ReleaseComObject(ppEnum); } return pRet; }
public static void SetFilterFormat(AMMediaType streamFormat, IBaseFilter filter) { if (filter == null) throw new ArgumentNullException("filter"); int hr; IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); if (pinsEnum == null) throw new SplicerException(Resources.ErrorPinsEnumeratorIsNull); var pins = new IPin[1]; while (true) { try { int fetched = 0; IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(pins.Length, pins, pcFetched); DsError.ThrowExceptionForHR(hr); fetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (fetched == 1) { // we have something IPin pin = pins[0]; string queryId; hr = pin.QueryId(out queryId); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); if (pinInfo.dir != PinDirection.Output) continue; var streamConfig = (IAMStreamConfig) pin; hr = streamConfig.SetFormat(streamFormat); DsError.ThrowExceptionForHR(hr); } else { break; } } finally { if (pins[0] != null) Marshal.ReleaseComObject(pins[0]); pins[0] = null; } } } finally { if (pinsEnum != null) Marshal.ReleaseComObject(pinsEnum); } }
public static IList<PinQueryInfo> EnumeratePins(IBaseFilter filter) { if (filter == null) throw new ArgumentNullException("filter"); int hr = 0; var pinsInfo = new List<PinQueryInfo>(); IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); if (pinsEnum == null) throw new InvalidOperationException("pinsEnum is null"); var pins = new IPin[1]; while (true) { try { int fetched = 0; IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(pins.Length, pins, pcFetched); DsError.ThrowExceptionForHR(hr); fetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (fetched == 1) { // we have something IPin pin = pins[0]; string queryId; hr = pin.QueryId(out queryId); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); pinsInfo.Add(new PinQueryInfo(pinInfo.dir, pinInfo.name, queryId)); } else { break; } } finally { if (pins[0] != null) Marshal.ReleaseComObject(pins[0]); pins[0] = null; } } } finally { if (pinsEnum != null) Marshal.ReleaseComObject(pinsEnum); } return pinsInfo; }
private IPin FindPin(string pin_name, IBaseFilter filter) { IEnumPins enum_pins; ReturnHR = filter.EnumPins(out enum_pins); IPin[] pin = new IPin[1]; while (enum_pins.Next(1, pin, IntPtr.Zero) == 0) { PinInfo pin_info; pin[0].QueryPinInfo(out pin_info); if (String.Compare(pin_info.name, pin_name) == 0) { DsUtils.FreePinInfo(pin_info); return pin[0]; } } LogError("Pin not found"); return null; }
public static void RenderOutputPins(IGraphBuilder graphBuilder, IBaseFilter filter) { if (graphBuilder == null) throw new ArgumentNullException("graphBuilder"); if (filter == null) throw new ArgumentNullException("filter"); int hr = 0; if (filter == null) throw new ArgumentNullException("filter"); IEnumPins enumPins; var pins = new IPin[1]; IntPtr fetched = IntPtr.Zero; hr = filter.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); try { while (enumPins.Next(pins.Length, pins, fetched) == 0) { try { PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Output) { hr = graphBuilder.Render(pins[0]); DsError.ThrowExceptionForHR(hr); } } finally { Marshal.ReleaseComObject(pins[0]); } } } finally { Marshal.ReleaseComObject(enumPins); } }
/// <summary> create the used COM components and get the interfaces. </summary> protected bool GetInterfaces() { VMR9Util.g_vmr9 = null; if (IsRadio == false) { Vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); // switch back to directx fullscreen mode Log.Info("RTSPPlayer: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); } //Type comtype = null; //object comobj = null; DsRect rect = new DsRect(); rect.top = 0; rect.bottom = GUIGraphicsContext.form.Height; rect.left = 0; rect.right = GUIGraphicsContext.form.Width; try { graphBuilder = (IGraphBuilder)new FilterGraph(); Log.Info("RTSPPlayer: add source filter"); if (IsRadio == false) { bool AddVMR9 = VMR9Util.g_vmr9 != null && VMR9Util.g_vmr9.AddVMR9(graphBuilder); if (!AddVMR9) { Log.Error("RTSPPlayer:Failed to add VMR9 to graph"); return false; } VMR9Util.g_vmr9.Enable(false); } _mpegDemux = (IBaseFilter)new MPEG2Demultiplexer(); graphBuilder.AddFilter(_mpegDemux, "MPEG-2 Demultiplexer"); _rtspSource = (IBaseFilter)new RtpSourceFilter(); int hr = graphBuilder.AddFilter((IBaseFilter)_rtspSource, "RTSP Source Filter"); if (hr != 0) { Log.Error("RTSPPlayer:unable to add RTSP source filter:{0:X}", hr); return false; } // add preferred video & audio codecs Log.Info("RTSPPlayer: add video/audio codecs"); string strVideoCodec = ""; string strAudioCodec = ""; string strAudiorenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters string postProcessingFilterSection = "mytv"; using (Settings xmlreader = new MPSettings()) { if (_mediaType == g_Player.MediaType.Video) { strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "movieplayer"; } else { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "mytv"; } enableDvbSubtitles = xmlreader.GetValueAsBool("tvservice", "dvbsubtitles", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool(postProcessingFilterSection, "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); if (IsRadio == false) { if (strVideoCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } } if (strAudioCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (enableDvbSubtitles == true) { try { _subtitleFilter = SubtitleRenderer.GetInstance().AddSubtitleFilter(graphBuilder); SubtitleRenderer.GetInstance().SetPlayer(this); dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } Log.Debug("Is subtitle fitler null? {0}", (_subtitleFilter == null)); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } if (strAudiorenderer.Length > 0) { audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } Log.Info("RTSPPlayer: load:{0}", m_strCurrentFile); IFileSourceFilter interfaceFile = (IFileSourceFilter)_rtspSource; if (interfaceFile == null) { Log.Error("RTSPPlayer:Failed to get IFileSourceFilter"); return false; } //Log.Info("RTSPPlayer: open file:{0}",filename); hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Log.Error("RTSPPlayer:Failed to open file:{0} :0x{1:x}", m_strCurrentFile, hr); return false; } #region connect rtspsource->demux Log.Info("RTSPPlayer:connect rtspsource->mpeg2 demux"); IPin pinTsOut = DsFindPin.ByDirection((IBaseFilter)_rtspSource, PinDirection.Output, 0); if (pinTsOut == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return false; } IPin pinDemuxIn = DsFindPin.ByDirection(_mpegDemux, PinDirection.Input, 0); if (pinDemuxIn == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return false; } hr = graphBuilder.Connect(pinTsOut, pinDemuxIn); if (hr != 0) { Log.Info("RTSPPlayer:failed to connect rtspsource->mpeg2 demux:{0:X}", hr); return false; } DirectShowUtil.ReleaseComObject(pinTsOut); DirectShowUtil.ReleaseComObject(pinDemuxIn); #endregion #region render demux output pins if (IsRadio) { Log.Info("RTSPPlayer:render audio demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { graphBuilder.Render(pins[0]); break; } } } } else { Log.Info("RTSPPlayer:render audio/video demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } graphBuilder.Render(pins[0]); } } #endregion // Connect DVB subtitle filter pins in the graph if (_mpegDemux != null && enableDvbSubtitles == true) { IMpeg2Demultiplexer demuxer = _mpegDemux as IMpeg2Demultiplexer; hr = demuxer.CreateOutputPin(GetTSMedia(), "Pcr", out _pinPcr); if (hr == 0) { Log.Info("RTSPPlayer:_pinPcr OK"); IPin pDemuxerPcr = DsFindPin.ByName(_mpegDemux, "Pcr"); IPin pSubtitlePcr = DsFindPin.ByName(_subtitleFilter, "Pcr"); hr = graphBuilder.Connect(pDemuxerPcr, pSubtitlePcr); } else { Log.Info("RTSPPlayer:Failed to create _pinPcr in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "Subtitle", out _pinSubtitle); if (hr == 0) { Log.Info("RTSPPlayer:_pinSubtitle OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "Subtitle"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "In"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinSubtitle in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "PMT", out _pinPMT); if (hr == 0) { Log.Info("RTSPPlayer:_pinPMT OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "PMT"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "PMT"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinPMT in demuxer:{0:X}", hr); } } if (IsRadio == false) { if (!VMR9Util.g_vmr9.IsVMR9Connected) { //VMR9 is not supported, switch to overlay Log.Info("RTSPPlayer: vmr9 not connected"); _mediaCtrl = null; Cleanup(); return false; } VMR9Util.g_vmr9.SetDeinterlaceMode(); } _mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; _mediaSeeking = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = graphBuilder as IBasicAudio; //DirectShowUtil.SetARMode(graphBuilder,AspectRatioMode.Stretched); DirectShowUtil.EnableDeInterlace(graphBuilder); if (VMR9Util.g_vmr9 != null) { m_iVideoWidth = VMR9Util.g_vmr9.VideoWidth; m_iVideoHeight = VMR9Util.g_vmr9.VideoHeight; } if (audioRendererFilter != null) { Log.Info("RTSPPlayer9:set reference clock"); IMediaFilter mp = graphBuilder as IMediaFilter; IReferenceClock clock = audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); Log.Info("RTSPPlayer9:set reference clock:{0:X}", hr); } Log.Info("RTSPPlayer: graph build successfull"); return true; } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("RTSPPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return false; } }
private void RenderNetDemux() { int hr; IEnumPins enumPins; IPin[] pins = new IPin[1]; hr = _netDmx.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); try { while (enumPins.Next(pins.Length, pins, IntPtr.Zero) == 0) { try { PinInfo pinInfo; IPin upstreamPin = pins[0]; hr = upstreamPin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); if (pinInfo.dir == PinDirection.Output) { IEnumMediaTypes enumMediaTypes; hr = upstreamPin.EnumMediaTypes(out enumMediaTypes); DsError.ThrowExceptionForHR(hr); AMMediaType[] mediaTypes = new AMMediaType[1]; if (enumMediaTypes.Next(1, mediaTypes, IntPtr.Zero) == 0) { AMMediaType mediaType = mediaTypes[0]; if (mediaType.majorType == MediaType.Video) { if ((mediaType.subType == new Guid("34363268-0000-0010-8000-00AA00389B71")) || // H264 (mediaType.subType == new Guid("3436324c-0000-0010-8000-00aa00389b71"))) { _decoderFilter = AddFilterByName(_graphBuilder, FilterCategory.LegacyAmFilterCategory, "LEAD H264 Decoder (3.0)"); ConnectFilters(_graphBuilder, _netDmx, pinInfo.name, _infPinTee, "Input", true); ConnectFilters(_graphBuilder, _infPinTee, "Output1", _decoderFilter, "XForm In", true); ConnectFilters(_graphBuilder, _infPinTee, "Output2", _bridgeSink, "Input 1", true); ConnectFilters(_graphBuilder, _decoderFilter, "XForm Out", _videoRender, "VMR Input0", true); } else if (mediaType.subType == new Guid("4B324A4C-0000-0010-8000-00AA00389B71")) { _decoderFilter = AddFilterByName(_graphBuilder, FilterCategory.LegacyAmFilterCategory, "LEAD MJ2K Decoder (2.0)"); ConnectFilters(_graphBuilder, _netDmx, pinInfo.name, _infPinTee, "Input", true); ConnectFilters(_graphBuilder, _infPinTee, "Output1", _decoderFilter, "XForm In", true); ConnectFilters(_graphBuilder, _infPinTee, "Output2", _bridgeSink, "Input 1", true); ConnectFilters(_graphBuilder, _decoderFilter, "XForm Out", _videoRender, "VMR Input0", true); } else if (mediaType.subType == MediaSubType.MJPG) { _decoderFilter = AddFilterByName(_graphBuilder, FilterCategory.LegacyAmFilterCategory, "LEAD MCMP/MJPEG Decoder (2.0)"); ConnectFilters(_graphBuilder, _netDmx, pinInfo.name, _infPinTee, "Input", true); ConnectFilters(_graphBuilder, _infPinTee, "Output1", _decoderFilter, "XForm In", true); ConnectFilters(_graphBuilder, _infPinTee, "Output2", _bridgeSink, "Input 1", true); ConnectFilters(_graphBuilder, _decoderFilter, "XForm Out", _videoRender, "VMR Input0", true); } else { throw new Exception("Can't Render--Unsupported codec in stream"); } } else { throw new Exception("Can't Render--Unsupported type - audio? not supported"); } } } } finally { Marshal.ReleaseComObject(pins[0]); } } } finally { Marshal.ReleaseComObject(enumPins); } }
public static void SetFilterFormat(AMMediaType streamFormat, IBaseFilter filter) { if (filter == null) { throw new ArgumentNullException("filter"); } int hr; IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); if (pinsEnum == null) { throw new SplicerException(Resources.ErrorPinsEnumeratorIsNull); } var pins = new IPin[1]; while (true) { try { int fetched = 0; IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(pins.Length, pins, pcFetched); DsError.ThrowExceptionForHR(hr); fetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (fetched == 1) { // we have something IPin pin = pins[0]; string queryId; hr = pin.QueryId(out queryId); DsError.ThrowExceptionForHR(hr); PinInfo pinInfo; hr = pin.QueryPinInfo(out pinInfo); DsError.ThrowExceptionForHR(hr); if (pinInfo.dir != PinDirection.Output) { continue; } var streamConfig = (IAMStreamConfig)pin; hr = streamConfig.SetFormat(streamFormat); DsError.ThrowExceptionForHR(hr); } else { break; } } finally { if (pins[0] != null) { Marshal.ReleaseComObject(pins[0]); } pins[0] = null; } } } finally { if (pinsEnum != null) { Marshal.ReleaseComObject(pinsEnum); } } }
/// <summary> create the used COM components and get the interfaces. </summary> protected bool GetInterfaces() { VMR9Util.g_vmr9 = null; if (IsRadio == false) { Vmr9 = VMR9Util.g_vmr9 = new VMR9Util(); // switch back to directx fullscreen mode Log.Info("RTSPPlayer: Enabling DX9 exclusive mode"); GUIMessage msg = new GUIMessage(GUIMessage.MessageType.GUI_MSG_SWITCH_FULL_WINDOWED, 0, 0, 0, 1, 0, null); GUIWindowManager.SendMessage(msg); } //Type comtype = null; //object comobj = null; DsRect rect = new DsRect(); rect.top = 0; rect.bottom = GUIGraphicsContext.form.Height; rect.left = 0; rect.right = GUIGraphicsContext.form.Width; try { graphBuilder = (IGraphBuilder) new FilterGraph(); Log.Info("RTSPPlayer: add source filter"); if (IsRadio == false) { bool AddVMR9 = VMR9Util.g_vmr9 != null && VMR9Util.g_vmr9.AddVMR9(graphBuilder); if (!AddVMR9) { Log.Error("RTSPPlayer:Failed to add VMR9 to graph"); return(false); } VMR9Util.g_vmr9.Enable(false); } _mpegDemux = (IBaseFilter) new MPEG2Demultiplexer(); graphBuilder.AddFilter(_mpegDemux, "MPEG-2 Demultiplexer"); _rtspSource = (IBaseFilter) new RtpSourceFilter(); int hr = graphBuilder.AddFilter((IBaseFilter)_rtspSource, "RTSP Source Filter"); if (hr != 0) { Log.Error("RTSPPlayer:unable to add RTSP source filter:{0:X}", hr); return(false); } // add preferred video & audio codecs Log.Info("RTSPPlayer: add video/audio codecs"); string strVideoCodec = ""; string strAudioCodec = ""; string strAudiorenderer = ""; int intFilters = 0; // FlipGer: count custom filters string strFilters = ""; // FlipGer: collect custom filters string postProcessingFilterSection = "mytv"; using (Settings xmlreader = new MPSettings()) { if (_mediaType == g_Player.MediaType.Video) { strVideoCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("movieplayer", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "movieplayer"; } else { strVideoCodec = xmlreader.GetValueAsString("mytv", "videocodec", ""); strAudioCodec = xmlreader.GetValueAsString("mytv", "audiocodec", ""); strAudiorenderer = xmlreader.GetValueAsString("mytv", "audiorenderer", "Default DirectSound Device"); postProcessingFilterSection = "mytv"; } enableDvbSubtitles = xmlreader.GetValueAsBool("tvservice", "dvbsubtitles", false); // FlipGer: load infos for custom filters int intCount = 0; while (xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") != "undefined") { if (xmlreader.GetValueAsBool(postProcessingFilterSection, "usefilter" + intCount.ToString(), false)) { strFilters += xmlreader.GetValueAsString(postProcessingFilterSection, "filter" + intCount.ToString(), "undefined") + ";"; intFilters++; } intCount++; } } string extension = Path.GetExtension(m_strCurrentFile).ToLowerInvariant(); if (IsRadio == false) { if (strVideoCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strVideoCodec); } } if (strAudioCodec.Length > 0) { DirectShowUtil.AddFilterToGraph(graphBuilder, strAudioCodec); } if (enableDvbSubtitles == true) { try { _subtitleFilter = SubtitleRenderer.GetInstance().AddSubtitleFilter(graphBuilder); SubtitleRenderer.GetInstance().SetPlayer(this); dvbSubRenderer = SubtitleRenderer.GetInstance(); } catch (Exception e) { Log.Error(e); } } Log.Debug("Is subtitle fitler null? {0}", (_subtitleFilter == null)); // FlipGer: add custom filters to graph string[] arrFilters = strFilters.Split(';'); for (int i = 0; i < intFilters; i++) { DirectShowUtil.AddFilterToGraph(graphBuilder, arrFilters[i]); } if (strAudiorenderer.Length > 0) { audioRendererFilter = DirectShowUtil.AddAudioRendererToGraph(graphBuilder, strAudiorenderer, false); } Log.Info("RTSPPlayer: load:{0}", m_strCurrentFile); IFileSourceFilter interfaceFile = (IFileSourceFilter)_rtspSource; if (interfaceFile == null) { Log.Error("RTSPPlayer:Failed to get IFileSourceFilter"); return(false); } //Log.Info("RTSPPlayer: open file:{0}",filename); hr = interfaceFile.Load(m_strCurrentFile, null); if (hr != 0) { Log.Error("RTSPPlayer:Failed to open file:{0} :0x{1:x}", m_strCurrentFile, hr); return(false); } #region connect rtspsource->demux Log.Info("RTSPPlayer:connect rtspsource->mpeg2 demux"); IPin pinTsOut = DsFindPin.ByDirection((IBaseFilter)_rtspSource, PinDirection.Output, 0); if (pinTsOut == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return(false); } IPin pinDemuxIn = DsFindPin.ByDirection(_mpegDemux, PinDirection.Input, 0); if (pinDemuxIn == null) { Log.Info("RTSPPlayer:failed to find output pin of tsfilesource"); return(false); } hr = graphBuilder.Connect(pinTsOut, pinDemuxIn); if (hr != 0) { Log.Info("RTSPPlayer:failed to connect rtspsource->mpeg2 demux:{0:X}", hr); return(false); } DirectShowUtil.ReleaseComObject(pinTsOut); DirectShowUtil.ReleaseComObject(pinDemuxIn); #endregion #region render demux output pins if (IsRadio) { Log.Info("RTSPPlayer:render audio demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == MediaType.Audio) { graphBuilder.Render(pins[0]); break; } } } } else { Log.Info("RTSPPlayer:render audio/video demux outputs"); IEnumPins enumPins; _mpegDemux.EnumPins(out enumPins); IPin[] pins = new IPin[2]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input) { continue; } graphBuilder.Render(pins[0]); } } #endregion // Connect DVB subtitle filter pins in the graph if (_mpegDemux != null && enableDvbSubtitles == true) { IMpeg2Demultiplexer demuxer = _mpegDemux as IMpeg2Demultiplexer; hr = demuxer.CreateOutputPin(GetTSMedia(), "Pcr", out _pinPcr); if (hr == 0) { Log.Info("RTSPPlayer:_pinPcr OK"); IPin pDemuxerPcr = DsFindPin.ByName(_mpegDemux, "Pcr"); IPin pSubtitlePcr = DsFindPin.ByName(_subtitleFilter, "Pcr"); hr = graphBuilder.Connect(pDemuxerPcr, pSubtitlePcr); } else { Log.Info("RTSPPlayer:Failed to create _pinPcr in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "Subtitle", out _pinSubtitle); if (hr == 0) { Log.Info("RTSPPlayer:_pinSubtitle OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "Subtitle"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "In"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinSubtitle in demuxer:{0:X}", hr); } hr = demuxer.CreateOutputPin(GetTSMedia(), "PMT", out _pinPMT); if (hr == 0) { Log.Info("RTSPPlayer:_pinPMT OK"); IPin pDemuxerSubtitle = DsFindPin.ByName(_mpegDemux, "PMT"); IPin pSubtitle = DsFindPin.ByName(_subtitleFilter, "PMT"); hr = graphBuilder.Connect(pDemuxerSubtitle, pSubtitle); } else { Log.Info("RTSPPlayer:Failed to create _pinPMT in demuxer:{0:X}", hr); } } if (IsRadio == false) { if (!VMR9Util.g_vmr9.IsVMR9Connected) { //VMR9 is not supported, switch to overlay Log.Info("RTSPPlayer: vmr9 not connected"); _mediaCtrl = null; Cleanup(); return(false); } VMR9Util.g_vmr9.SetDeinterlaceMode(); } _mediaCtrl = (IMediaControl)graphBuilder; mediaEvt = (IMediaEventEx)graphBuilder; _mediaSeeking = (IMediaSeeking)graphBuilder; mediaPos = (IMediaPosition)graphBuilder; basicAudio = graphBuilder as IBasicAudio; //DirectShowUtil.SetARMode(graphBuilder,AspectRatioMode.Stretched); DirectShowUtil.EnableDeInterlace(graphBuilder); if (VMR9Util.g_vmr9 != null) { m_iVideoWidth = VMR9Util.g_vmr9.VideoWidth; m_iVideoHeight = VMR9Util.g_vmr9.VideoHeight; } if (audioRendererFilter != null) { Log.Info("RTSPPlayer9:set reference clock"); IMediaFilter mp = graphBuilder as IMediaFilter; IReferenceClock clock = audioRendererFilter as IReferenceClock; hr = mp.SetSyncSource(null); hr = mp.SetSyncSource(clock); Log.Info("RTSPPlayer9:set reference clock:{0:X}", hr); } Log.Info("RTSPPlayer: graph build successfull"); return(true); } catch (Exception ex) { Error.SetError("Unable to play movie", "Unable build graph for VMR9"); Log.Error("RTSPPlayer:exception while creating DShow graph {0} {1}", ex.Message, ex.StackTrace); CloseInterfaces(); return(false); } }
// Tear down everything downstream of a given filter public static int NukeDownstream(IFilterGraph graph, IBaseFilter filter) { if (filter == null) { return(WinAPI.E_FAIL); } IEnumPins enumPins = null; IPin[] pins = new IPin[1] { null }; try { int hr = filter.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); enumPins.Reset(); // start at the first pin while (enumPins.Next(1, pins, IntPtr.Zero) == 0) { if (pins[0] != null) { PinDirection pindir; pins[0].QueryDirection(out pindir); if (pindir == PinDirection.Output) { IPin pTo = null; pins[0].ConnectedTo(out pTo); if (pTo != null) { PinInfo pi; hr = pTo.QueryPinInfo(out pi); if (hr == 0) { NukeDownstream(graph, pi.filter); graph.Disconnect(pTo); graph.Disconnect(pins[0]); graph.RemoveFilter(pi.filter); Util.ReleaseComObject(ref pi.filter); DsUtils.FreePinInfo(pi); } Marshal.ReleaseComObject(pTo); } } Marshal.ReleaseComObject(pins[0]); } } return(0); } catch (Exception ex) { System.Diagnostics.Debug.WriteLine(ex.ToString()); } finally { Marshal.ReleaseComObject(enumPins); } return(WinAPI.E_FAIL); }
public static void AddPreferredFilters(IGraphBuilder graphBuilder, IBaseFilter sourceFilter) { using (Settings xmlreader = new MPSettings()) { bool autodecodersettings = xmlreader.GetValueAsBool("movieplayer", "autodecodersettings", false); if (!autodecodersettings) // the user has not chosen automatic graph building by merits { // bool vc1ICodec,vc1Codec,xvidCodec = false; - will come later bool aacCodec = false; bool h264Codec = false; // check the output pins of the splitter for known media types IEnumPins pinEnum = null; if (sourceFilter.EnumPins(out pinEnum) == 0) { int fetched = 0; IPin[] pins = new IPin[1]; while (pinEnum.Next(1, pins, out fetched) == 0 && fetched > 0) { IPin pin = pins[0]; PinDirection pinDirection; if (pin.QueryDirection(out pinDirection) == 0 && pinDirection == PinDirection.Output) { IEnumMediaTypes enumMediaTypesVideo = null; if (pin.EnumMediaTypes(out enumMediaTypesVideo) == 0) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; while (enumMediaTypesVideo.Next(1, mediaTypes, out typesFetched) == 0 && typesFetched > 0) { if (mediaTypes[0].majorType == MediaType.Video && (mediaTypes[0].subType == MediaSubType.H264 || mediaTypes[0].subType == MEDIASUBTYPE_AVC1)) { Log.Instance.Info("found H264 video on output pin"); h264Codec = true; } else if (mediaTypes[0].majorType == MediaType.Audio && mediaTypes[0].subType == MediaSubType.LATMAAC) { Log.Instance.Info("found AAC audio on output pin"); aacCodec = true; } } DirectShowUtil.ReleaseComObject(enumMediaTypesVideo); } } DirectShowUtil.ReleaseComObject(pin); } DirectShowUtil.ReleaseComObject(pinEnum); } // add filters for found media types to the graph as configured in MP if (h264Codec) { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "h264videocodec", ""))); } else { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "mpeg2videocodec", ""))); } if (aacCodec) { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "aacaudiocodec", ""))); } else { DirectShowUtil.ReleaseComObject( DirectShowUtil.AddFilterToGraph(graphBuilder, xmlreader.GetValueAsString("movieplayer", "mpeg2audiocodec", ""))); } } } }
/// <summary> /// This filter has an input pin matching one of the pins in the list. /// </summary> /// <param name="thisFilter"></param> /// <param name="inputPins"></param> /// <returns></returns> private bool FilterHasInputPin(IBaseFilter thisFilter, List<IPin> inputPins) { if (inputPins.Count == 0) return false; IEnumPins enumPins; thisFilter.EnumPins(out enumPins); IPin p; uint fetched; enumPins.Next(1, out p, out fetched); while (fetched == 1) { _PinDirection pinDir; p.QueryDirection(out pinDir); if (pinDir == _PinDirection.PINDIR_INPUT) { if (inputPins.Contains(p)) { return true; } } enumPins.Next(1, out p, out fetched); } return false; }
public static void RenderUnconnectedOutputPins(IGraphBuilder graphBuilder, IBaseFilter baseFilter) { if (baseFilter == null) return; int fetched; IEnumPins pinEnum; int hr = baseFilter.EnumPins(out pinEnum); DsError.ThrowExceptionForHR(hr); if (hr == 0 && pinEnum != null) { pinEnum.Reset(); IPin[] pins = new IPin[1]; while (pinEnum.Next(1, pins, out fetched) == 0 && fetched > 0) { PinDirection pinDir; pins[0].QueryDirection(out pinDir); if (pinDir == PinDirection.Output && !HasConnection(pins[0])) { FilterInfo i; PinInfo pinInfo; string pinName = string.Empty; if (baseFilter.QueryFilterInfo(out i) == 0) { if (pins[0].QueryPinInfo(out pinInfo) == 0) { Log.Debug("Filter: {0} - try to connect: {1}", i.achName, pinInfo.name); pinName = pinInfo.name; DsUtils.FreePinInfo(pinInfo); } } ReleaseComObject(i.pGraph); hr = graphBuilder.Render(pins[0]); if (hr != 0) Log.Debug(" - failed"); } ReleaseComObject(pins[0]); } ReleaseComObject(pinEnum); } }
/// <summary> /// Reconnects all filters in graph. /// </summary> /// <param name="graphBuilder">IGraphBuilder</param> /// <param name="filter">Current IBaseFilter in graph</param> static void ReConnectAll(IGraphBuilder graphBuilder, IBaseFilter filter) { IEnumPins pinEnum; FilterInfo info = FilterGraphTools.QueryFilterInfoAndFree(filter); IntPtr ptrFetched = Marshal.AllocCoTaskMem(4); int hr = filter.EnumPins(out pinEnum); if ((hr == 0) && (pinEnum != null)) { ServiceRegistration.Get <ILogger>().Info("got pins"); IPin[] pins = new IPin[1]; int iFetched; int iPinNo = 0; do { // Get the next pin iPinNo++; hr = pinEnum.Next(1, pins, ptrFetched); // In case of error stop the pin enumeration if (hr != 0) { break; } iFetched = Marshal.ReadInt32(ptrFetched); if (iFetched == 1 && pins[0] != null) { PinInfo pinInfo; hr = pins[0].QueryPinInfo(out pinInfo); if (hr == 0) { ServiceRegistration.Get <ILogger>().Info(" got pin#{0}:{1}", iPinNo - 1, pinInfo.name); FilterGraphTools.FreePinInfo(pinInfo); } else { ServiceRegistration.Get <ILogger>().Info(" got pin:?"); } PinDirection pinDir; pins[0].QueryDirection(out pinDir); if (pinDir == PinDirection.Output) { IntPtr other_ptr; hr = pins[0].ConnectedTo(out other_ptr); if (hr == 0 && other_ptr != IntPtr.Zero) { ServiceRegistration.Get <ILogger>().Info("Reconnecting {0}:{1}", info.achName, pinInfo.name); hr = graphBuilder.Reconnect(pins[0]); if (hr != 0) { ServiceRegistration.Get <ILogger>().Warn("Reconnect failed: {0}:{1}, code: 0x{2:x}", info.achName, pinInfo.name, hr); } IPin other = Marshal.GetObjectForIUnknown(other_ptr) as IPin; PinInfo otherPinInfo; other.QueryPinInfo(out otherPinInfo); ReConnectAll(graphBuilder, otherPinInfo.filter); FilterGraphTools.FreePinInfo(otherPinInfo); Marshal.ReleaseComObject(other); } } Marshal.ReleaseComObject(pins[0]); } else { ServiceRegistration.Get <ILogger>().Info("no pins?"); break; } }while (iFetched == 1); FilterGraphTools.TryRelease(ref pinEnum); Marshal.FreeCoTaskMem(ptrFetched); } }
public static bool TryConnect(IGraphBuilder graphbuilder, IBaseFilter source, Guid mediaType, IBaseFilter targetFilter) { bool connected = false; IEnumPins enumPins; int hr = source.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); IPin[] pins = new IPin[1]; int fetched = 0; while (enumPins.Next(1, pins, out fetched) == 0) { if (fetched != 1) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Output) { IEnumMediaTypes enumMediaTypes; pins[0].EnumMediaTypes(out enumMediaTypes); AMMediaType[] mediaTypes = new AMMediaType[20]; int fetchedTypes; enumMediaTypes.Next(20, mediaTypes, out fetchedTypes); for (int i = 0; i < fetchedTypes; ++i) { if (mediaTypes[i].majorType == mediaType) { if ( graphbuilder.ConnectDirect(pins[0], DsFindPin.ByDirection(targetFilter, PinDirection.Input, 0), null) >= 0) { connected = true; break; } } } } ReleaseComObject(pins[0]); } ReleaseComObject(enumPins); return connected; }
public static IPin GetPinByName(IBaseFilter iBF, string name) { IEnumPins iEnum; iBF.EnumPins(out iEnum); IPin pin; uint fetched; iEnum.Next(1, out pin, out fetched); while (fetched == 1) { if (String.Compare(name, Pin.Name(pin)) == 0) { return pin; } iEnum.Next(1, out pin, out fetched); } return null; }
public static ArrayList GetPins(IBaseFilter iBF) { ArrayList pins = new ArrayList(); IEnumPins iEnum; iBF.EnumPins(out iEnum); IPin pin; uint pcFetched = 0; // All DShow examples seem to use 1 for cPins even though it supports an array // This works out well in practice because the RCW converter listed it as an out IPin iEnum.Next(1, out pin, out pcFetched); while(pcFetched == 1) { pins.Add(pin); iEnum.Next(1, out pin, out pcFetched); } return pins; }
public static void LogOutputPinsConnectionRecursive(IBaseFilter filter, string previous = "") { bool log = true; IEnumPins pinEnum = null; if (filter.EnumPins(out pinEnum) == 0) { FilterInfo sourceFilterInfo; filter.QueryFilterInfo(out sourceFilterInfo); int fetched = 0; IPin[] pins = new IPin[1]; while (pinEnum.Next(1, pins, out fetched) == 0 && fetched > 0) { IPin pin = pins[0]; PinDirection pinDirection; if (pin.QueryDirection(out pinDirection) == 0 && pinDirection == PinDirection.Output) { log = false; IPin connectedPin; if (pin.ConnectedTo(out connectedPin) == 0 && connectedPin != null) { PinInfo connectedPinInfo; connectedPin.QueryPinInfo(out connectedPinInfo); FilterInfo connectedFilterInfo; connectedPinInfo.filter.QueryFilterInfo(out connectedFilterInfo); if (previous == "") previous = sourceFilterInfo.achName; DirectShowUtil.ReleaseComObject(connectedPin, 2000); IBaseFilter connectedFilter; if (connectedFilterInfo.pGraph.FindFilterByName(connectedFilterInfo.achName, out connectedFilter) == 0 && connectedFilter != null) { LogOutputPinsConnectionRecursive(connectedFilter, previous + string.Format(" --> {0}", connectedFilterInfo.achName)); DirectShowUtil.ReleaseComObject(connectedFilter); } } DirectShowUtil.ReleaseComObject(pin, 2000); } } } DirectShowUtil.ReleaseComObject(pinEnum, 2000); if (log) Log.Instance.Debug(previous); }
public static bool RenderOutputPins(IGraphBuilder graphBuilder, IBaseFilter filter, int maxPinsToRender, bool tryAllFilters) { int pinsRendered = 0; bool bAllConnected = true; IEnumPins pinEnum; FilterInfo info; filter.QueryFilterInfo(out info); ReleaseComObject(info.pGraph); int hr = filter.EnumPins(out pinEnum); if ((hr == 0) && (pinEnum != null)) { Log.Info("got pins"); pinEnum.Reset(); IPin[] pins = new IPin[1]; int iFetched; int iPinNo = 0; do { // Get the next pin //Log.Info(" get pin:{0}",iPinNo); iPinNo++; hr = pinEnum.Next(1, pins, out iFetched); if (hr == 0) { if (iFetched == 1 && pins[0] != null) { PinInfo pinInfo = new PinInfo(); hr = pins[0].QueryPinInfo(out pinInfo); DsUtils.FreePinInfo(pinInfo); if (hr == 0) { Log.Info(" got pin#{0}:{1}", iPinNo - 1, pinInfo.name); } else { Log.Info(" got pin:?"); } PinDirection pinDir; pins[0].QueryDirection(out pinDir); if (pinDir == PinDirection.Output) { IPin pConnectPin = null; hr = pins[0].ConnectedTo(out pConnectPin); if (hr != 0 || pConnectPin == null) { hr = 0; if (TryConnect(graphBuilder, info.achName, pins[0], tryAllFilters)) //if ((hr=graphBuilder.Render(pins[0])) == 0) { Log.Info(" render ok"); } else { Log.Error(" render {0} failed:{1:x}, trying alternative graph builder", pinInfo.name, hr); if ((hr = graphBuilder.Render(pins[0])) == 0) { Log.Info(" render ok"); } else { Log.Error(" render failed:{0:x}", hr); bAllConnected = false; } } pinsRendered++; } if (pConnectPin != null) { ReleaseComObject(pConnectPin); } pConnectPin = null; //else Log.Info("pin is already connected"); } ReleaseComObject(pins[0]); } else { iFetched = 0; Log.Info("no pins?"); break; } } else { iFetched = 0; } } while (iFetched == 1 && pinsRendered < maxPinsToRender && bAllConnected); ReleaseComObject(pinEnum); } return bAllConnected; }
protected ArrayList findAudioSources(ICaptureGraphBuilder2 graphBuilder, IBaseFilter deviceFilter) { ArrayList sources = new ArrayList(); IAMAudioInputMixer audioInputMixer = deviceFilter as IAMAudioInputMixer; if ( audioInputMixer != null ) { // Get a pin enumerator off the filter IEnumPins pinEnum; int hr = deviceFilter.EnumPins( out pinEnum ); pinEnum.Reset(); if( (hr == 0) && (pinEnum != null) ) { // Loop through each pin IPin[] pins = new IPin[1]; int f; do { // Get the next pin hr = pinEnum.Next( 1, pins, out f ); if( (hr == 0) && (pins[0] != null) ) { // Is this an input pin? PinDirection dir = PinDirection.Output; hr = pins[0].QueryDirection( out dir ); if( (hr == 0) && (dir == (PinDirection.Input)) ) { // Add the input pin to the sources list AudioSource source = new AudioSource( pins[0] ); sources.Add( source ); } pins[0] = null; } } while( hr == 0 ); Marshal.ReleaseComObject( pinEnum ); pinEnum = null; } } // If there is only one source, don't return it // because there is nothing for the user to choose. // (Hopefully that single source is already enabled). if ( sources.Count == 1 ) sources.Clear(); return( sources ); }
private IPin FindPin(IBaseFilter filter, PinDirection direction, Guid mediaType, Guid pinCategory, string preferredName) { if (Guid.Empty != pinCategory) { int idx = 0; do { IPin pinByCategory = DsFindPin.ByCategory(filter, pinCategory, idx); if (pinByCategory != null) { if (IsMatchingPin(pinByCategory, direction, mediaType)) { return(pinByCategory); } Marshal.ReleaseComObject(pinByCategory); } else { break; } idx++; }while (true); } if (!string.IsNullOrEmpty(preferredName)) { IPin pinByName = DsFindPin.ByName(filter, preferredName); if (pinByName != null && IsMatchingPin(pinByName, direction, mediaType)) { return(pinByName); } Marshal.ReleaseComObject(pinByName); } IEnumPins pinsEnum; IPin[] pins = new IPin[1]; int hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); while (pinsEnum.Next(1, pins, IntPtr.Zero) == 0) { IPin pin = pins[0]; if (pin != null) { if (IsMatchingPin(pin, direction, mediaType)) { return(pin); } Marshal.ReleaseComObject(pin); } } return(null); }
public static void DisconnectPins(IBaseFilter filter) { int hr = 0; if (filter == null) throw new ArgumentNullException("filter"); IEnumPins enumPins; var pins = new IPin[1]; IntPtr fetched = IntPtr.Zero; hr = filter.EnumPins(out enumPins); DsError.ThrowExceptionForHR(hr); try { while (enumPins.Next(pins.Length, pins, fetched) == 0) { try { hr = pins[0].Disconnect(); DsError.ThrowExceptionForHR(hr); } finally { Marshal.ReleaseComObject(pins[0]); } } } finally { Marshal.ReleaseComObject(enumPins); } }
private async void Button_Click(object sender, RoutedEventArgs e) { OpenFileDialog lopenFileDialog = new OpenFileDialog(); lopenFileDialog.AddExtension = true; var lresult = lopenFileDialog.ShowDialog(); if (lresult != true) { return; } IBaseFilter lDSoundRender = new DSoundRender() as IBaseFilter; m_pGraph.AddFilter(lDSoundRender, "Audio Renderer"); int k = 0; IPin[] lAudioRendererPins = new IPin[1]; IEnumPins ppEnum; k = lDSoundRender.EnumPins(out ppEnum); k = ppEnum.Next(1, lAudioRendererPins, IntPtr.Zero); var lCaptureManagerEVRMultiSinkFactory = await CaptureManagerVideoRendererMultiSinkFactory.getInstance().getICaptureManagerEVRMultiSinkFactoryAsync(); uint lMaxVideoRenderStreamCount = await lCaptureManagerEVRMultiSinkFactory.getMaxVideoRenderStreamCountAsync(); if (lMaxVideoRenderStreamCount == 0) { return; } List <object> lOutputNodesList = await lCaptureManagerEVRMultiSinkFactory.createOutputNodesAsync( IntPtr.Zero, mEVRDisplay.Surface.texture, 1); if (lOutputNodesList.Count == 0) { return; } IBaseFilter lVideoMixingRenderer9 = (IBaseFilter)lOutputNodesList[0]; var h = m_pGraph.AddFilter(lVideoMixingRenderer9, "lVideoMixingRenderer9"); IPin[] lVideoRendererPin = new IPin[1]; k = lVideoMixingRenderer9.EnumPins(out ppEnum); k = ppEnum.Next(1, lVideoRendererPin, IntPtr.Zero); IBaseFilter m_SourceFilter = null; m_pGraph.AddSourceFilter(lopenFileDialog.FileName, null, out m_SourceFilter); IEnumPins lEnumPins = null; m_SourceFilter.EnumPins(out lEnumPins); IPin[] lPins = new IPin[1]; while (lEnumPins.Next(1, lPins, IntPtr.Zero) == 0) { IEnumMediaTypes lIEnumMediaTypes; lPins[0].EnumMediaTypes(out lIEnumMediaTypes); AMMediaType[] ppMediaTypes = new AMMediaType[1]; while (lIEnumMediaTypes.Next(1, ppMediaTypes, IntPtr.Zero) == 0) { var gh = ppMediaTypes[0].subType; if (ppMediaTypes[0].majorType == DirectShowLib.MediaType.Video) { k = m_pGraph.Connect(lPins[0], lVideoRendererPin[0]); } } foreach (var item in lPins) { k = m_pGraph.Render(item); } } IMediaControl lIMediaControl = m_pGraph as IMediaControl; k = lIMediaControl.Run(); }
public static IPin FindPinForMajorType(IBaseFilter filter, PinDirection direction, Guid majorType) { if (filter == null) throw new ArgumentNullException("filter"); int hr = 0; IEnumPins pinsEnum = null; try { hr = filter.EnumPins(out pinsEnum); DsError.ThrowExceptionForHR(hr); var pins = new IPin[1]; int numberFetched = 1; while (numberFetched > 0) { IntPtr pcFetched = Marshal.AllocCoTaskMem(4); try { hr = pinsEnum.Next(1, pins, pcFetched); DsError.ThrowExceptionForHR(hr); numberFetched = Marshal.ReadInt32(pcFetched); } finally { Marshal.FreeCoTaskMem(pcFetched); } if (numberFetched > 0) { PinDirection currentPinDirection; hr = pins[0].QueryDirection(out currentPinDirection); DsError.ThrowExceptionForHR(hr); if (currentPinDirection != direction) continue; IEnumMediaTypes mediaTypesEnum = null; try { var mediaTypes = new AMMediaType[1]; pins[0].EnumMediaTypes(out mediaTypesEnum); int numberFetched2 = 1; while (numberFetched2 > 0) { IntPtr fetched2 = IntPtr.Zero; try { hr = mediaTypesEnum.Next(1, mediaTypes, fetched2); DsError.ThrowExceptionForHR(hr); numberFetched2 = Marshal.ReadInt32(fetched2); } finally { Marshal.FreeCoTaskMem(fetched2); } if (numberFetched2 > 0) { if (mediaTypes[0].majorType == majorType) { // success, return the pin return pins[0]; } } Marshal.ReleaseComObject(pins[0]); } } finally { if (mediaTypesEnum != null) Marshal.ReleaseComObject(mediaTypesEnum); } } } } finally { if (pinsEnum != null) Marshal.ReleaseComObject(pinsEnum); } return null; }
protected void removeDownstream(IBaseFilter filter, bool removeFirstFilter) { IEnumPins pins; int num = filter.EnumPins(out pins); pins.Reset(); if ((num == 0) && (pins != null)) { IPin[] ppPins = new IPin[1]; do { int num2; num = pins.Next(1, ppPins, out num2); if ((num == 0) && (ppPins[0] != null)) { IPin ppPin = null; ppPins[0].ConnectedTo(out ppPin); if (ppPin != null) { PinInfo pInfo = new PinInfo(); num = ppPin.QueryPinInfo(out pInfo); if ((num == 0) && (pInfo.dir == PinDirection.Input)) { this.removeDownstream(pInfo.filter, true); this.graphBuilder.Disconnect(ppPin); this.graphBuilder.Disconnect(ppPins[0]); if ((pInfo.filter != this.videoCompressorFilter) && (pInfo.filter != this.audioCompressorFilter)) { this.graphBuilder.RemoveFilter(pInfo.filter); } } Marshal.ReleaseComObject(pInfo.filter); Marshal.ReleaseComObject(ppPin); } Marshal.ReleaseComObject(ppPins[0]); } } while (num == 0); Marshal.ReleaseComObject(pins); pins = null; } }
// from 'DShowUtil.cpp' public int GetPin( IBaseFilter filter, PinDirection dirrequired, int num, out IPin ppPin ) { ppPin = null; int hr; IEnumPins pinEnum; hr = filter.EnumPins( out pinEnum ); if( (hr < 0) || (pinEnum == null) ) return hr; IPin[] pins = new IPin[1]; int f; PinDirection dir; do { hr = pinEnum.Next( 1, pins, out f ); if( (hr != 0) || (pins[0] == null) ) break; dir = (PinDirection) 3; hr = pins[0].QueryDirection( out dir ); if( (hr == 0) && (dir == dirrequired) ) { if( num == 0 ) { ppPin = pins[0]; pins[0] = null; break; } num--; } Marshal.ReleaseComObject( pins[0] ); pins[0] = null; } while( hr == 0 ); Marshal.ReleaseComObject( pinEnum ); pinEnum = null; return hr; }
/// <summary> /// Checks if the pin connections can be kept, or if a graph rebuilding is necessary. /// </summary> /// <param name="baseFilter">Filter to check</param> /// <returns>True if graph needs to be rebuilt</returns> private static bool GraphNeedsRebuild(IBaseFilter baseFilter) { IEnumPins pinEnum; int hr = baseFilter.EnumPins(out pinEnum); if (hr != 0 || pinEnum == null) { return(true); } IPin[] pins = new IPin[1]; IntPtr ptrFetched = Marshal.AllocCoTaskMem(4); for (; ;) { hr = pinEnum.Next(1, pins, ptrFetched); if (hr != 0 || Marshal.ReadInt32(ptrFetched) == 0) { break; } try { IPin other = null; IntPtr other_ptr; if (pins[0].ConnectedTo(out other_ptr) == 0 && other_ptr != IntPtr.Zero) { try { other = Marshal.GetObjectForIUnknown(other_ptr) as IPin; PinInfo pinInfo; pins[0].QueryPinInfo(out pinInfo); FilterInfo filterInfo = FilterGraphTools.QueryFilterInfoAndFree(pinInfo.filter); try { if (!QueryConnect(pins[0], other)) { ServiceRegistration.Get <ILogger>().Info("Graph needs a rebuild. Filter: {0}, Pin: {1}", filterInfo.achName, pinInfo.name); return(true); } } finally { FilterGraphTools.FreePinInfo(pinInfo); } } finally { if (other != null && Marshal.IsComObject(other)) { Marshal.ReleaseComObject(other); } } } } finally { Marshal.ReleaseComObject(pins[0]); } } Marshal.ReleaseComObject(pinEnum); Marshal.FreeCoTaskMem(ptrFetched); ServiceRegistration.Get <ILogger>().Info("Graph does not need a rebuild"); return(false); }