private static void PerformConnection(IFilter srcFilter, XElement pinNode, IGraph graph) { var connectedToNode = new Guid(pinNode.Attribute("ConnectedToNode").Value); string connectedToPin = pinNode.Attribute("ConnectedToPin").Value; string pinName = pinNode.Attribute("Name").Value; IFilter destFilter = graph.Filters.First(filter => filter.NodeGuid == connectedToNode); IPin outputPin = srcFilter.Pins.First(pin => pin.Name == pinName); IPin receivePin = destFilter.Pins.First(pin => pin.Name == connectedToPin); outputPin.Connect(receivePin); }
private static void Connect_up(int dInput, int dOutput) { object source = null, inputD = null; DsDevice[] devices; devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioRendererCategory); DsDevice device = devices[dOutput]; Guid iid = typeof(IBaseFilter).GUID; device.Mon.BindToObject(null, null, ref iid, out source); m_objFilterGraph = (IGraphBuilder) new FilterGraph(); m_objFilterGraph.AddFilter((IBaseFilter)source, "Audio Input pin (rendered)"); devices = DsDevice.GetDevicesOfCat(FilterCategory.AudioInputDevice); device = devices[dInput]; // iid change? device.Mon.BindToObject(null, null, ref iid, out inputD); m_objFilterGraph.AddFilter((IBaseFilter)inputD, "Capture"); int result; IEnumPins pInputPin = null, pOutputPin = null; // Pin enumeration IPin pIn = null, pOut = null; // Pins try { IBaseFilter newI = (IBaseFilter)inputD; result = newI.EnumPins(out pInputPin);// Enumerate the pin if (result.Equals(0)) { // Get hold of the pin as seen in GraphEdit newI.FindPin("Capture", out pIn); } IBaseFilter ibfO = (IBaseFilter)source; ibfO.EnumPins(out pOutputPin);//Enumerate the pin ibfO.FindPin("Audio Input pin (rendered)", out pOut); try { pIn.Connect(pOut, null); // Connect the input pin to output pin } catch (Exception ex) { Console.WriteLine(ex.Message); } } catch (Exception ex) { Console.WriteLine(ex.Message); } m_objBasicAudio = m_objFilterGraph as IBasicAudio; m_objMediaControl = m_objFilterGraph as IMediaControl; }
void RestorePinConnection(IPin pin, Dictionary <string, IPin[]> oldConnections) { IPin[] remotePins; if (oldConnections.TryGetValue(pin.Id, out remotePins)) { foreach (var remotePin in remotePins) { if (remotePin.Graph == null || remotePin.Container == null) { return; } try { pin.Connect(remotePin); } catch (Exception) { // ignoring exception during connection restore } } } }
public void TestConnectDisconnectConnectedToConnectionMediaType() { int hr; IBaseFilter aviSplitter = null; IBaseFilter ibfAVISource = null; IPin pinIn = null; IPin pinOut = null; IFilterGraph2 graphBuilder = new FilterGraph() as IFilterGraph2; try { ibfAVISource = new AsyncReader() as IBaseFilter; // Add it to the graph hr = graphBuilder.AddFilter(ibfAVISource, "Ds.NET AsyncReader"); Marshal.ThrowExceptionForHR(hr); // Set the file name IFileSourceFilter fsf = ibfAVISource as IFileSourceFilter; hr = fsf.Load(@"foo.avi", null); Marshal.ThrowExceptionForHR(hr); pinOut = DsFindPin.ByDirection(ibfAVISource, PinDirection.Output, 0); // Get the avi splitter aviSplitter = (IBaseFilter) new AviSplitter(); // Add it to the graph hr = graphBuilder.AddFilter(aviSplitter, "Ds.NET AviSplitter"); Marshal.ThrowExceptionForHR(hr); pinIn = DsFindPin.ByDirection(aviSplitter, PinDirection.Input, 0); Assert.IsNotNull(pinOut); Assert.IsNotNull(pinIn); // Test Connect hr = pinOut.Connect(pinIn, null); Marshal.ThrowExceptionForHR(hr); // Test ConnectedTo IPin pinConnect; hr = pinOut.ConnectedTo(out pinConnect); Marshal.ThrowExceptionForHR(hr); Assert.AreEqual(pinIn, pinConnect); // Test ConnectionMediaType AMMediaType mediaType = new AMMediaType(); hr = pinIn.ConnectionMediaType(mediaType); Marshal.ThrowExceptionForHR(hr); Assert.IsNotNull(mediaType); Assert.IsNotNull(mediaType.majorType); // Test Disconnect hr = pinOut.Disconnect(); Marshal.ThrowExceptionForHR(hr); } finally { Marshal.ReleaseComObject(graphBuilder); } }
public static void tオーディオレンダラをNullレンダラに変えてフォーマットを取得する(IGraphBuilder graphBuilder, out WaveFormat wfx, out byte[] wfx拡張データ) { int hr = 0; IBaseFilter audioRenderer = null; IPin rendererInputPin = null; IPin rendererConnectedOutputPin = null; IBaseFilter nullRenderer = null; IPin nullRendererInputPin = null; wfx = null; wfx拡張データ = new byte[0]; try { // audioRenderer を探す。 audioRenderer = CDirectShow.tオーディオレンダラを探して返す(graphBuilder); if (audioRenderer == null) { return; // なかった } #region [ 音量ゼロで一度再生する。(オーディオレンダラの入力ピンMediaTypeが、接続時とは異なる「正しいもの」に変わる可能性があるため。)] //----------------- { // ここに来た時点で、グラフのビデオレンダラは無効化(NullRendererへの置換や除去など)しておくこと。 // さもないと、StopWhenReady() 時に一瞬だけ Activeウィンドウが表示されてしまう。 var mediaCtrl = (IMediaControl)graphBuilder; var basicAudio = (IBasicAudio)graphBuilder; basicAudio.put_Volume(-10000); // 最小音量 // グラフを再生してすぐ止める。(Paused → Stopped へ遷移する) mediaCtrl.StopWhenReady(); // グラフが Stopped に遷移完了するまで待つ。(StopWhenReady() はグラフが Stopped になるのを待たずに帰ってくる。) FilterState fs = FilterState.Paused; hr = CWin32.S_FALSE; while (fs != FilterState.Stopped || hr != CWin32.S_OK) { hr = mediaCtrl.GetState(10, out fs); } // 終了処理。 basicAudio.put_Volume(0); // 最大音量 basicAudio = null; mediaCtrl = null; } //----------------- #endregion // audioRenderer の入力ピンを探す。 rendererInputPin = t最初の入力ピンを探して返す(audioRenderer); if (rendererInputPin == null) { return; } // WAVEフォーマットを取得し、wfx 引数へ格納する。 var type = new AMMediaType(); hr = rendererInputPin.ConnectionMediaType(type); DsError.ThrowExceptionForHR(hr); try { wfx = new WaveFormat(); #region [ type.formatPtr から wfx に、拡張領域を除くデータをコピーする。] //----------------- var wfxTemp = new WaveFormatEx(); // SharpDX.Multimedia.WaveFormat は Marshal.PtrToStructure() で使えないので、それが使える DirectShowLib.WaveFormatEx を介して取得する。(面倒…) Marshal.PtrToStructure(type.formatPtr, (object)wfxTemp); wfx = WaveFormat.CreateCustomFormat((WaveFormatEncoding)wfxTemp.wFormatTag, wfxTemp.nSamplesPerSec, wfxTemp.nChannels, wfxTemp.nAvgBytesPerSec, wfxTemp.nBlockAlign, wfxTemp.wBitsPerSample); //----------------- #endregion #region [ 拡張領域が存在するならそれを wfx拡張データ に格納する。 ] //----------------- int nWaveFormatEx本体サイズ = 16 + 2; // sizeof( WAVEFORMAT ) + sizof( WAVEFORMATEX.cbSize ) int nはみ出しサイズbyte = type.formatSize - nWaveFormatEx本体サイズ; if (nはみ出しサイズbyte > 0) { wfx拡張データ = new byte[nはみ出しサイズbyte]; var hGC = GCHandle.Alloc(wfx拡張データ, GCHandleType.Pinned); // 動くなよー unsafe { byte *src = (byte *)type.formatPtr.ToPointer(); byte *dst = (byte *)hGC.AddrOfPinnedObject().ToPointer(); CWin32.CopyMemory(dst, src + nWaveFormatEx本体サイズ, (uint)nはみ出しサイズbyte); } hGC.Free(); } //----------------- #endregion } finally { if (type != null) { DsUtils.FreeAMMediaType(type); } } // audioRenderer につながる出力ピンを探す。 hr = rendererInputPin.ConnectedTo(out rendererConnectedOutputPin); DsError.ThrowExceptionForHR(hr); // audioRenderer をグラフから切断する。 rendererInputPin.Disconnect(); rendererConnectedOutputPin.Disconnect(); // audioRenderer をグラフから除去する。 hr = graphBuilder.RemoveFilter(audioRenderer); DsError.ThrowExceptionForHR(hr); // nullRenderer を作成し、グラフに追加する。 nullRenderer = (IBaseFilter) new NullRenderer(); hr = graphBuilder.AddFilter(nullRenderer, "Audio Null Renderer"); DsError.ThrowExceptionForHR(hr); // nullRenderer の入力ピンを探す。 hr = nullRenderer.FindPin("In", out nullRendererInputPin); DsError.ThrowExceptionForHR(hr); // nullRenderer をグラフに接続する。 hr = rendererConnectedOutputPin.Connect(nullRendererInputPin, null); DsError.ThrowExceptionForHR(hr); } finally { CCommon.tReleaseComObject(ref nullRendererInputPin); CCommon.tReleaseComObject(ref nullRenderer); CCommon.tReleaseComObject(ref rendererConnectedOutputPin); CCommon.tReleaseComObject(ref rendererInputPin); CCommon.tReleaseComObject(ref audioRenderer); } }