/// <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); } }
private static bool TestMediaTypes(IPin pin, IPin receiver) { bool ret = false; IEnumMediaTypes types; pin.EnumMediaTypes(out types); types.Reset(); while (true) { AMMediaType[] mediaTypes = new AMMediaType[1]; int typesFetched; int hr = types.Next(1, mediaTypes, out typesFetched); if (hr != 0 || typesFetched == 0) { break; } //Log.Info("Check output type: {0}, {1}", mediaTypes[0].majorType, // mediaTypes[0].subType); if (receiver.QueryAccept(mediaTypes[0]) == 0) { //Log.Info("Accepted!"); ret = true; break; } } ReleaseComObject(types); //Log.Info("-----EndofTypes"); return ret; }
public 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; for (;;) { AMMediaType[] types = new AMMediaType[1]; int fetched; hr = enumTypes.Next(1, types, out fetched); if (hr != 0 || fetched == 0) { break; } count++; if (other.QueryAccept(types[0]) == 0) { return true; } } PinInfo info; PinInfo infoOther; pin.QueryPinInfo(out info); DsUtils.FreePinInfo(info); other.QueryPinInfo(out infoOther); DsUtils.FreePinInfo(infoOther); Log.Info("Pins {0} and {1} do not accept each other. Tested {2} media types", info.name, infoOther.name, count); return false; }
/// <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); } }
public int Connect(IPin pReceivePin, AMMediaType pmt) { Monitor.Enter(this); int hr = S_OK; pin = null; pintype = null; allocator = null; string id = "Unnamed pin"; pReceivePin.QueryId(out id); PinInfo pi = new PinInfo(); hr = pReceivePin.QueryPinInfo(out pi); if (hr == S_OK) { FilterInfo fi = new FilterInfo(); hr = pi.filter.QueryFilterInfo(out fi); if (hr == S_OK) { id += (" (" + fi.achName); } Guid guid; hr = pi.filter.GetClassID(out guid); if (hr == S_OK) { id += (", " + guid.ToString()); } id += ")"; } try { AMMediaType amt = null; if (pmt != null) { amt = pmt; } else #if false { IEnumMediaTypes ie; hr = pReceivePin.EnumMediaTypes(out ie); int fetched; int alloc = Marshal.SizeOf(typeof(AMMediaType)); IntPtr mtypePtr = Marshal.AllocCoTaskMem(alloc); while (ie.Next(1, mtypePtr, out fetched) == S_OK) { amt = new AMMediaType(); Marshal.PtrToStructure(mtypePtr, amt); hr = pReceivePin.QueryAccept(amt); if (hr == S_OK) { break; } DsUtils.FreeAMMediaType(amt); amt = null; } if (fetched == 0) { amt = null; } Marshal.FreeCoTaskMem(mtypePtr); } if (amt == null) #endif { amt = mediatype; } hr = pReceivePin.QueryAccept(amt); if (hr == S_FALSE) { log.InfoFormat("No media type for pin '{0}'", id); Monitor.Exit(this); return VFW_E_NO_ACCEPTABLE_TYPES; } hr = pReceivePin.ReceiveConnection(this, amt); if (hr == VFW_E_TYPE_NOT_ACCEPTED) { log.InfoFormat("No connection to pin '{0}'", id); Monitor.Exit(this); return VFW_E_NO_ACCEPTABLE_TYPES; } DsError.ThrowExceptionForHR(hr); pin = pReceivePin; pintype = amt; } catch (Exception e) { LogUtil.ExceptionLog.ErrorFormat("Caught exception in connect ({0}): {1}{2}", id, e.Message, e.StackTrace); pin = null; pintype = null; allocator = null; Monitor.Exit(this); return VFW_E_NO_TRANSPORT; } Monitor.Exit(this); log.InfoFormat("Connected to pin '{0}'", id); return S_OK; }
public int Connect(IPin pReceivePin, AMMediaType pmt) { unchecked { if (_ConnectedPin != null) { return((int)HRESULT.VFW_E_ALREADY_CONNECTED); } PinDirection pd; pReceivePin.QueryDirection(out pd); if (pd == _Direction) { return((int)HRESULT.VFW_E_INVALID_DIRECTION); } PinInfo pi; pReceivePin.QueryPinInfo(out pi); FilterInfo fi; pi.filter.QueryFilterInfo(out fi); Debug.WriteLine(fi.achName + "." + pi.name, _Name + " connect attempt from"); if (pi.name == "Subpicture Input") { } HRESULT hr = HRESULT.VFW_E_NO_ACCEPTABLE_TYPES; // // Try match our media types with the specific one requested // if any... // if (null != (pmt)) { for (int i = 0; i < MediaTypes.Count; i++) { if (MatchesPartial(MediaTypes[i], pmt)) { hr = OnReceiveConnection(pReceivePin, MediaTypes[i]); if (hr != HRESULT.S_OK) { // pReceivePin.Disconnect(); } else { break; } } } } // // Otherwise try force-connect all of the ones we like. // if (hr != HRESULT.S_OK) { for (int i = 0; i < MediaTypes.Count; i++) { AMMediaType newMT = new AMMediaType(); Copy(MediaTypes[i], newMT); hr = (HRESULT)pReceivePin.QueryAccept(newMT); if (hr == HRESULT.S_OK) { hr = OnReceiveConnection(pReceivePin, newMT); if (hr != HRESULT.S_OK) { //pReceivePin.Disconnect(); } else { break; } } } } // // Failing that, try connect with any of their numerous // supported types.. // if (hr != HRESULT.S_OK) { IEnumMediaTypes en; pReceivePin.EnumMediaTypes(out en); en.Reset(); /* * Unsafe pointer edition * ====================== * I was experminting AMMediaType as a value struct type * for better marshalling. * * AMMediaType* types = null; * int fetched = 0; * do * { * HRESULT r = en.Next(1, (AMMediaType**)&types, out fetched); * if (r != HRESULT.S_OK || fetched == 0) || break; || AMMediaType tmp = *types; || for (int x = 0; x < MediaTypes.Count; x++) || { || if ((MediaTypes[x].majorType == tmp.majorType || && MediaTypes[x].subType == tmp.subType) || AcceptsAnyMedia) || { || hr = OnReceiveConnection(pReceivePin, tmp); //MediaTypes[x] || || if (hr != HRESULT.S_OK) || { || pReceivePin.Disconnect(); || } || else || break; || } || } || AMMediaType.Free(tmp); ||} while (fetched > 0);*/ AMMediaType[] types = new AMMediaType[100]; IntPtr ptr = ToPtr(types); IntPtr fetched = IntPtr.Zero; en.Next(10, types, fetched); types = FromIntPtr(ptr, fetched.ToInt32()); if (fetched.ToInt32() > 0 && types != null) { for (int x = 0; x < MediaTypes.Count; x++) { for (int i = 0; i < fetched.ToInt32(); i++) { if ((MediaTypes[x].majorType == types[i].majorType && MediaTypes[x].subType == types[i].subType) || AcceptsAnyMedia) { hr = OnReceiveConnection(pReceivePin, types[i]); if (hr != HRESULT.S_OK) { //pReceivePin.Disconnect(); } else { break; } } } if (hr == HRESULT.S_OK) { break; } } } for (int i = 0; i < fetched.ToInt32(); i++) { Free(types[i]); } if (Marshal.IsComObject(en)) { Marshal.ReleaseComObject(en); } } if (hr != HRESULT.S_OK) { // Final clean up this.Disconnect(); if (Marshal.IsComObject(pReceivePin)) { Marshal.ReleaseComObject(pReceivePin); } // Connect failed, but may have returned S_FALSE // so this ensures a better return code. hr = HRESULT.VFW_E_NO_ACCEPTABLE_TYPES; } if (hr == HRESULT.S_OK) { ResolveConnectedFilter(); } return((int)hr); } }