public static bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin) { IPin other; int hr = pin.ConnectedTo(out other); bool allDisconnected = true; PinInfo info; pin.QueryPinInfo(out info); DsUtils.FreePinInfo(info); if (hr == 0 && other != null) { other.QueryPinInfo(out info); if (!DisconnectAllPins(graphBuilder, info.filter)) { allDisconnected = false; } hr = pin.Disconnect(); if (hr != 0) { allDisconnected = false; } hr = other.Disconnect(); if (hr != 0) { allDisconnected = false; } DsUtils.FreePinInfo(info); Marshal.ReleaseComObject(other); } else { } return(allDisconnected); }
public int Disconnect() { try { OnDisconnect(); if (_ConnectedPin != null) { _ConnectedPin.BeginFlush(); //_ConnectedPin.EndOfStream(); // deadlock - dont do this. _ConnectedPin.Disconnect(); _ConnectedPin.EndFlush(); } if (_ConnectedPin != null && Marshal.IsComObject(_ConnectedPin)) { GC.ReRegisterForFinalize(_ConnectedPin); Marshal.FinalReleaseComObject(_ConnectedPin); } _ConnectedPin = null; } catch (Exception x) { Debug.WriteLine("Failed to disconnect pin " + x); } return((int)HRESULT.S_OK); // Disconnect must not fail }
public static void DisconnectAll(this IPin pin) { foreach (var c in pin.Connections) { pin.Disconnect(c); } }
public static void tビデオレンダラをグラフから除去する(IGraphBuilder graphBuilder) { int hr = 0; IBaseFilter videoRenderer = null; IPin renderInputPin = null; IPin connectedOutputPin = null; try { // videoRenderer を探す。 CDirectShow.tビデオレンダラとその入力ピンを探して返す(graphBuilder, out videoRenderer, out renderInputPin); if (videoRenderer == null || renderInputPin == null) { return; // なかった } #region [ renderInputPin へ接続している前段の出力ピン connectedOutputPin を探す。 ] //----------------- renderInputPin.ConnectedTo(out connectedOutputPin); //----------------- #endregion if (connectedOutputPin == null) { return; // なかった } // 前段の出力ピンとビデオレンダラの入力ピンを切断する。双方向から切断しないとグラフから切り離されないので注意。 renderInputPin.Disconnect(); connectedOutputPin.Disconnect(); // ビデオレンダラをグラフから除去。 graphBuilder.RemoveFilter(videoRenderer); } finally { CCommon.tReleaseComObject(ref connectedOutputPin); CCommon.tReleaseComObject(ref renderInputPin); CCommon.tReleaseComObject(ref videoRenderer); } }
/// <summary> /// Disconnects a single Pin. /// </summary> /// <param name="graphBuilder">IGraphBuilder</param> /// <param name="pin">Pin to disconnect</param> /// <returns>True if successful</returns> bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin) { IntPtr other_ptr; int hr = pin.ConnectedTo(out other_ptr); bool allDisconnected = true; if (hr == 0 && other_ptr != IntPtr.Zero) { IPin other = Marshal.GetObjectForIUnknown(other_ptr) as IPin; PinInfo info; pin.QueryPinInfo(out info); ServiceRegistration.Get <ILogger>().Info("Disconnecting pin {0}", info.name); FilterGraphTools.FreePinInfo(info); other.QueryPinInfo(out info); if (!DisconnectAllPins(graphBuilder, info.filter)) { allDisconnected = false; } FilterGraphTools.FreePinInfo(info); hr = pin.Disconnect(); if (hr != 0) { allDisconnected = false; ServiceRegistration.Get <ILogger>().Error("Error disconnecting: {0:x}", hr); } hr = other.Disconnect(); if (hr != 0) { allDisconnected = false; ServiceRegistration.Get <ILogger>().Error("Error disconnecting other: {0:x}", hr); } Marshal.ReleaseComObject(other); } else { ServiceRegistration.Get <ILogger>().Info(" Not connected"); } return(allDisconnected); }
public static IBaseFilter AddToGraph(IGraphBuilder graphBuilder) { IBaseFilter vob = null; using (Settings xmlreader = new MPSettings()) { string engineType = xmlreader.GetValueAsString("subtitles", "engine", "DirectVobSub"); XySubFilter = engineType.Equals("XySubFilter"); } if (!XySubFilter) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob); if (vob == null) { //Try the "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob); } } else { //Try the XySubFilter "autoload" filter. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterAutoload, out vob); if (vob != null) { return(vob); } //Try the XySubFilter "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterNormal, out vob); if (vob != null) { return(vob); } vob = DirectShowUtil.AddFilterToGraph(graphBuilder, "XySubFilter"); if (vob == null) { Log.Warn("VideoPlayerVMR9: DirectVobSub or XySubFilter filter not found! You need to install XySubFilter"); return(null); } Log.Debug("VideoPlayerVMR9: VobSub filter added to graph"); return(vob); } //if the directvobsub filter has not been added to the graph. (i.e. with evr) //we add a bit more intelligence to determine if subtitles are enabled. //and if subtitles are present for the video / movie then we add it if necessary to the graph. if (vob == null) { Log.Info("VideoPlayerVMR9: No VobSub filter in the current graph"); //the filter has not been added lets check if it should be added or not. //add the filter to the graph vob = DirectShowUtil.AddFilterToGraph(graphBuilder, "DirectVobSub"); if (vob == null) { Log.Warn("VideoPlayerVMR9: DirectVobSub or XySubFilter filter not found! You need to install VSFilter"); return(null); } Log.Debug("VideoPlayerVMR9: VobSub filter added to graph"); } else // VobSub already loaded { return(vob); } // Check if Haali Media Splitter is in the graph. IBaseFilter hms = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.HaaliGuid, out hms); if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroska, out hms); } if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.MPCMatroskaSource, out hms); } if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.LAVFilter, out hms); } if (hms == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.LAVFilterSource, out hms); } if (hms != null) { IPin pinSubTo = null; // It is. Connect it' subtitle output pin (if any) to Vobsub's subtitle input. pinSubTo = DirectShowUtil.FindPin(hms, PinDirection.Output, "Subtitle"); if (pinSubTo == null) { while (true) { IPin freeSubtitle = DirectShowUtil.FindFirstFreePinSub(hms, PinDirection.Output, ""); IPin freeVobSub = DirectShowUtil.FindFirstFreePin(vob, PinDirection.Input, "Input"); if (freeSubtitle != null && freeVobSub != null) { Log.Debug("VideoPlayerVMR9: Connecting Matroska's subtitle output to VobSub's input."); graphBuilder.Connect(freeSubtitle, freeVobSub); DirectShowUtil.ReleaseComObject(freeSubtitle); freeSubtitle = null; DirectShowUtil.ReleaseComObject(freeVobSub); freeVobSub = null; } else { break; } } } DirectShowUtil.ReleaseComObject(hms); hms = null; if (pinSubTo != null) { Log.Debug("VideoPlayerVMR9: Connecting Haali's subtitle output to VobSub's input."); // Try to render pins IPin pinVobSubSub = DirectShowUtil.FindPin(vob, PinDirection.Input, "Input"); // If pinSubTo is already connected (disconnect it) graphBuilder.Disconnect(pinSubTo); graphBuilder.Connect(pinSubTo, pinVobSubSub); DirectShowUtil.ReleaseComObject(pinSubTo); pinSubTo = null; DirectShowUtil.ReleaseComObject(pinVobSubSub); pinVobSubSub = null; } } // Now check if vobsub's video input is not connected. // Check only if vmr9 is connected (render was successful). VMR9Util Vmr9 = VMR9Util.g_vmr9; if (Vmr9.IsVMR9Connected) { Log.Debug("VideoPlayerVMR9: Connect VobSub's video pins"); IPin pinVobSubVideoIn = DsFindPin.ByDirection(vob, PinDirection.Input, 0); IPin pinVobSubVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0); // This is the pin that we will connect to vobsub's input. IPin pinVideoTo = Vmr9.PinConnectedTo; IPin pinVideoFrom = null; pinVideoTo.ConnectedTo(out pinVideoFrom); pinVideoTo.Disconnect(); pinVideoFrom.Disconnect(); //Now make connection to VobSub int hr = graphBuilder.Connect(pinVideoTo, pinVobSubVideoIn); //hr = graphBuilder.Render(pinVideoFrom); if (hr != 0) { Log.Error("VideoPlayerVMR9: could not connect Vobsub's input video pin"); return(null); } hr = graphBuilder.Connect(pinVobSubVideoOut, pinVideoFrom); //hr = graphBuilder.Render(pinVobSubVideoOut); if (hr != 0) { Log.Error("VideoPlayerVMR9: could not connect Vobsub's output video pin"); return(null); } Log.Debug("VideoPlayerVMR9: Vobsub's video pins connected"); DirectShowUtil.ReleaseComObject(pinVideoTo); pinVideoTo = null; DirectShowUtil.ReleaseComObject(pinVobSubVideoIn); pinVobSubVideoIn = null; DirectShowUtil.ReleaseComObject(pinVobSubVideoOut); pinVobSubVideoOut = null; DirectShowUtil.ReleaseComObject(pinVideoFrom); pinVideoFrom = null; } Vmr9 = null; return(vob); }
public static bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin) { IPin other; int hr = pin.ConnectedTo(out other); bool allDisconnected = true; PinInfo info; pin.QueryPinInfo(out info); DsUtils.FreePinInfo(info); if (hr == 0 && other != null) { other.QueryPinInfo(out info); if (!DisconnectAllPins(graphBuilder, info.filter)) { allDisconnected = false; } hr = pin.Disconnect(); if (hr != 0) { allDisconnected = false; } hr = other.Disconnect(); if (hr != 0) { allDisconnected = false; } DsUtils.FreePinInfo(info); Marshal.ReleaseComObject(other); } else { } return allDisconnected; }
private static bool TryConnect(IGraphBuilder graphBuilder, string filtername, IPin outputPin, IBaseFilter to) { bool ret = false; int hr; FilterInfo info; PinInfo outputInfo; to.QueryFilterInfo(out info); ReleaseComObject(info.pGraph); outputPin.QueryPinInfo(out outputInfo); DsUtils.FreePinInfo(outputInfo); if (info.achName.Equals(filtername)) { return false; //do not connect to self } Log.Debug("Testing filter: {0}", info.achName); IEnumPins enumPins; IPin[] pins = new IPin[1]; to.EnumPins(out enumPins); do { int pinsFetched; hr = enumPins.Next(1, pins, out pinsFetched); if (hr != 0 || pinsFetched == 0) { break; } PinDirection direction; pins[0].QueryDirection(out direction); if (direction == PinDirection.Input && !HasConnection(pins[0])) // && TestMediaTypes(outputPin, pins[0])) { PinInfo pinInfo; pins[0].QueryPinInfo(out pinInfo); DsUtils.FreePinInfo(pinInfo); Log.Debug("Testing compatibility to {0}", pinInfo.name); //ListMediaTypes(pins[0]); //hr = outputPin.Connect(pins[0], null); hr = graphBuilder.ConnectDirect(outputPin, pins[0], null); if (hr == 0) { Log.Debug("Connection succeeded"); if (RenderOutputPins(graphBuilder, to)) { Log.Info("Successfully rendered pin {0}:{1} to {2}:{3}.", filtername, outputInfo.name, info.achName, pinInfo.name); ret = true; ReleaseComObject(pins[0]); break; } else { Log.Debug("Rendering got stuck. Trying next filter, and disconnecting {0}!", outputInfo.name); outputPin.Disconnect(); pins[0].Disconnect(); } } else { Log.Debug("Could not connect, filters are not compatible: {0:x}", hr); } } ReleaseComObject(pins[0]); } while (true); ReleaseComObject(enumPins); if (!ret) { Log.Debug("Dead end. Could not successfully connect pin {0} to filter {1}!", outputInfo.name, info.achName); } return ret; }
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); } }
public static void RemoveFromGraph(IGraphBuilder graphBuilder) { IBaseFilter vob = null; DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob); if (vob == null) { //Try the "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob); if (vob == null) { return; } } Log.Info("VideoPlayerVMR9: DirectVobSub in graph, removing..."); // Check where video inputs are connected IPin pinVideoIn = DsFindPin.ByDirection(vob, PinDirection.Input, 0); IPin pinVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0); //find directvobsub's video output pin source input pin IPin pinVideoTo = null; pinVideoOut.ConnectedTo(out pinVideoTo); //find directvobsub's video input pin source output pin IPin pinVideoFrom = null; pinVideoIn.ConnectedTo(out pinVideoFrom); int hr; if (pinVideoFrom != null) { hr = pinVideoFrom.Disconnect(); if (hr != 0) { Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting source pin"); } } if (pinVideoTo != null) { hr = pinVideoTo.Disconnect(); if (hr != 0) { Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting destination pin"); } } //remove the DirectVobSub filter from the graph graphBuilder.RemoveFilter(vob); DirectShowUtil.ReleaseComObject(vob); vob = null; //reconnect the source output pin to the vmr9/evr filter hr = graphBuilder.Connect(pinVideoFrom, pinVideoTo); //hr = graphBuilder.Render(pinVideoFrom); DirectShowUtil.ReleaseComObject(pinVideoFrom); pinVideoFrom = null; DirectShowUtil.ReleaseComObject(pinVideoTo); pinVideoTo = null; DirectShowUtil.ReleaseComObject(pinVideoOut); pinVideoOut = null; DirectShowUtil.ReleaseComObject(pinVideoIn); pinVideoIn = null; if (hr != 0) { Log.Error("VideoPlayerVMR9: Could not connect video out to video renderer: {0}", hr); } else { Log.Debug("VideoPlayerVMR9: DirectVobSub graph rebuild finished"); } }
public void SetUpForTs(ISampleGrabberCB grabber, int methodToCall) { FilterGraphTools.DisconnectPins(mpeg2Demux); //FilterGraphTools.DisconnectPins(demodulator); FilterGraphTools.DisconnectPins(audioRenderer); FilterGraphTools.DisconnectPins(videoRenderer); //graphBuilder.RemoveFilter(audioRenderer); //graphBuilder.RemoveFilter(videoRenderer); sampleGrabber = (ISampleGrabber) new SampleGrabber(); AMMediaType media = new AMMediaType(); media.majorType = MediaType.Stream; media.subType = MediaSubType.Mpeg2Transport; media.formatType = FormatType.MpegStreams; sampleGrabber.SetOneShot(false); sampleGrabber.SetBufferSamples(true); int hr = sampleGrabber.SetMediaType(media); DsError.ThrowExceptionForHR(hr); graphBuilder.AddFilter((IBaseFilter)sampleGrabber, "Sample Grabber"); nullRenderer = (IBaseFilter) new NullRenderer(); graphBuilder.AddFilter(nullRenderer, "NULL Renderer"); IPin pinIn = DsFindPin.ByName((IBaseFilter)sampleGrabber, "Input"); IPin pinOut = DsFindPin.ByDirection(capture, PinDirection.Output, 0); IEnumMediaTypes eMedia; pinOut.EnumMediaTypes(out eMedia); AMMediaType[] mediaTypes = new AMMediaType[1]; eMedia.Next(mediaTypes.Length, mediaTypes, IntPtr.Zero); hr = sampleGrabber.SetMediaType(mediaTypes[0]); DsError.ThrowExceptionForHR(hr); pinOut.Disconnect(); PinInfo info; pinOut.QueryPinInfo(out info); hr = graphBuilder.ConnectDirect(pinOut, pinIn, mediaTypes[0]); //hr = graphBuilder.Connect(pinOut, pinIn); DsError.ThrowExceptionForHR(hr); // Release the Pin Marshal.ReleaseComObject(pinIn); pinIn = DsFindPin.ByName(nullRenderer, "In"); pinOut = DsFindPin.ByName((IBaseFilter)sampleGrabber, "Output"); hr = graphBuilder.Connect(pinOut, pinIn); DsError.ThrowExceptionForHR(hr); sampleGrabber.SetCallback(grabber, methodToCall); // Release the Pin Marshal.ReleaseComObject(pinIn); pinIn = null; }
/// <summary> /// Disconnects a single Pin. /// </summary> /// <param name="graphBuilder">IGraphBuilder</param> /// <param name="pin">Pin to disconnect</param> /// <returns>True if successful</returns> bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin) { IntPtr other_ptr; int hr = pin.ConnectedTo(out other_ptr); bool allDisconnected = true; if (hr == 0 && other_ptr != IntPtr.Zero) { IPin other = Marshal.GetObjectForIUnknown(other_ptr) as IPin; PinInfo info; pin.QueryPinInfo(out info); ServiceRegistration.Get<ILogger>().Info("Disconnecting pin {0}", info.name); FilterGraphTools.FreePinInfo(info); other.QueryPinInfo(out info); if (!DisconnectAllPins(graphBuilder, info.filter)) allDisconnected = false; FilterGraphTools.FreePinInfo(info); hr = pin.Disconnect(); if (hr != 0) { allDisconnected = false; ServiceRegistration.Get<ILogger>().Error("Error disconnecting: {0:x}", hr); } hr = other.Disconnect(); if (hr != 0) { allDisconnected = false; ServiceRegistration.Get<ILogger>().Error("Error disconnecting other: {0:x}", hr); } Marshal.ReleaseComObject(other); } else { ServiceRegistration.Get<ILogger>().Info(" Not connected"); } return allDisconnected; }
/* * protected void InitAudioSampleGrabber() * { * // Get the graph builder * IGraphBuilder graphBuilder = (mediaControl as IGraphBuilder); * if (graphBuilder == null) * return; * * try * { * // Build the sample grabber * sampleGrabber = Activator.CreateInstance(Type.GetTypeFromCLSID(Filters.SampleGrabber, true)) * as ISampleGrabber; * * if (sampleGrabber == null) * return; * * // Add it to the filter graph * int hr = graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "ProTONE_SampleGrabber"); * DsError.ThrowExceptionForHR(hr); * * AMMediaType mtAudio = new AMMediaType(); * mtAudio.majorType = MediaType.Audio; * mtAudio.subType = MediaSubType.PCM; * mtAudio.formatPtr = IntPtr.Zero; * * _actualAudioFormat = null; * * hr = sampleGrabber.SetMediaType(mtAudio); * DsError.ThrowExceptionForHR(hr); * * hr = sampleGrabber.SetBufferSamples(true); * DsError.ThrowExceptionForHR(hr); * * hr = sampleGrabber.SetOneShot(false); * DsError.ThrowExceptionForHR(hr); * * hr = sampleGrabber.SetCallback(this, 1); * DsError.ThrowExceptionForHR(hr); * * sampleAnalyzerMustStop.Reset(); * sampleAnalyzerThread = new Thread(new ThreadStart(SampleAnalyzerLoop)); * sampleAnalyzerThread.Priority = ThreadPriority.Highest; * sampleAnalyzerThread.Start(); * } * catch(Exception ex) * { * Logger.LogException(ex); * } * * rotEntry = new DsROTEntry(graphBuilder as IFilterGraph); * }*/ protected void InitAudioSampleGrabber_v2() { // Get the graph builder IGraphBuilder graphBuilder = (mediaControl as IGraphBuilder); if (graphBuilder == null) { return; } try { // Build the sample grabber sampleGrabber = Activator.CreateInstance(Type.GetTypeFromCLSID(Filters.SampleGrabber, true)) as ISampleGrabber; if (sampleGrabber == null) { return; } // Add it to the filter graph int hr = graphBuilder.AddFilter(sampleGrabber as IBaseFilter, "ProTONE_SampleGrabber_v2"); DsError.ThrowExceptionForHR(hr); IBaseFilter ffdAudioDecoder = null; IPin ffdAudioDecoderOutput = null; IPin soundDeviceInput = null; IPin sampleGrabberInput = null; IPin sampleGrabberOutput = null; IntPtr pSoundDeviceInput = IntPtr.Zero; // When using FFDShow, typically we'll find // a ffdshow Audio Decoder connected to the sound device filter // // i.e. [ffdshow Audio Decoder] --> [DirectSound Device] // // Our audio sample grabber supports only PCM sample input and output. // Its entire processing is based on this assumption. // // Thus need to insert the audio sample grabber between the ffdshow Audio Decoder and the sound device // because this is the only place where we can find PCM samples. The sound device only accepts PCM. // // So we need to turn this graph: // // .. -->[ffdshow Audio Decoder]-->[DirectSound Device] // // into this: // // .. -->[ffdshow Audio Decoder]-->[Sample grabber]-->[DirectSound Device] // // Actions to do to achieve the graph change: // // 1. Locate the ffdshow Audio Decoder in the graph // 2. Find its output pin and the pin that it's connected to // 3. Locate the input and output pins of sample grabber // 4. Disconnect the ffdshow Audio Decoder and its correspondent (sound device input pin) // 5. Connect the ffdshow Audio Decoder to sample grabber input // 6. Connect the sample grabber output to sound device input // that's all. // -------------- // 1. Locate the ffdshow Audio Decoder in the graph hr = graphBuilder.FindFilterByName("ffdshow Audio Decoder", out ffdAudioDecoder); DsError.ThrowExceptionForHR(hr); // 2. Find its output pin and the pin that it's connected to hr = ffdAudioDecoder.FindPin("Out", out ffdAudioDecoderOutput); DsError.ThrowExceptionForHR(hr); hr = ffdAudioDecoderOutput.ConnectedTo(out pSoundDeviceInput); DsError.ThrowExceptionForHR(hr); soundDeviceInput = new DSPin(pSoundDeviceInput).Value; // 3. Locate the input and output pins of sample grabber hr = (sampleGrabber as IBaseFilter).FindPin("In", out sampleGrabberInput); DsError.ThrowExceptionForHR(hr); hr = (sampleGrabber as IBaseFilter).FindPin("Out", out sampleGrabberOutput); DsError.ThrowExceptionForHR(hr); // 4. Disconnect the ffdshow Audio Decoder and its correspondent (sound device input pin) hr = ffdAudioDecoderOutput.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = soundDeviceInput.Disconnect(); DsError.ThrowExceptionForHR(hr); // 5. Connect the ffdshow Audio Decoder to sample grabber input hr = graphBuilder.Connect(ffdAudioDecoderOutput, sampleGrabberInput); DsError.ThrowExceptionForHR(hr); // 6. Connect the sample grabber output to sound device input hr = graphBuilder.Connect(sampleGrabberOutput, soundDeviceInput); DsError.ThrowExceptionForHR(hr); AMMediaType mtAudio = new AMMediaType(); mtAudio.majorType = MediaType.Audio; mtAudio.subType = MediaSubType.PCM; mtAudio.formatPtr = IntPtr.Zero; _actualAudioFormat = null; sampleGrabber.SetMediaType(mtAudio); sampleGrabber.SetBufferSamples(true); sampleGrabber.SetOneShot(false); sampleGrabber.SetCallback(this, 1); sampleAnalyzerMustStop.Reset(); sampleAnalyzerThread = new Thread(new ThreadStart(SampleAnalyzerLoop)); sampleAnalyzerThread.Priority = ThreadPriority.Highest; sampleAnalyzerThread.Start(); } catch (Exception ex) { Logger.LogException(ex); } rotEntry = new DsROTEntry(graphBuilder as IFilterGraph); }
/// <summary> build the capture graph for grabber. </summary> private void SetupGraph(string FileName) { int hr; // Get the graphbuilder object this.graphBuilder = new FilterGraph() as IGraphBuilder; this.mediaControl = this.graphBuilder as IMediaControl; this.mediaSeeking = this.graphBuilder as IMediaSeeking; this.mediaEvent = this.graphBuilder as IMediaEvent; try { // Get the SampleGrabber interface this.sampleGrabber = new SampleGrabber() as ISampleGrabber; this.sampleGrabberFilter = sampleGrabber as IBaseFilter; ConfigureSampleGrabber(sampleGrabber); // Add the frame grabber to the graph hr = graphBuilder.AddFilter(sampleGrabberFilter, "Ds.NET Sample Grabber"); DsError.ThrowExceptionForHR(hr); IBaseFilter aviSplitter = new AviSplitter() as IBaseFilter; // Add the aviSplitter to the graph hr = graphBuilder.AddFilter(aviSplitter, "Splitter"); DsError.ThrowExceptionForHR(hr); // Have the graph builder construct its appropriate graph automatically hr = this.graphBuilder.RenderFile(FileName, null); DsError.ThrowExceptionForHR(hr); #if DEBUG m_rot = new DsROTEntry(graphBuilder); #endif // Remove the video renderer filter IBaseFilter defaultVideoRenderer = null; graphBuilder.FindFilterByName("Video Renderer", out defaultVideoRenderer); graphBuilder.RemoveFilter(defaultVideoRenderer); // Disconnect anything that is connected // to the output of the sample grabber IPin iPinSampleGrabberOut = DsFindPin.ByDirection(sampleGrabberFilter, PinDirection.Output, 0); IPin iPinVideoIn; hr = iPinSampleGrabberOut.ConnectedTo(out iPinVideoIn); if (hr == 0) { // Disconnect the sample grabber output from the attached filters hr = iPinVideoIn.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = iPinSampleGrabberOut.Disconnect(); DsError.ThrowExceptionForHR(hr); } else { // Try other way round because automatic renderer could not build // graph including the sample grabber IPin iPinAVISplitterOut = DsFindPin.ByDirection(aviSplitter, PinDirection.Output, 0); IPin iPinAVISplitterIn; hr = iPinAVISplitterOut.ConnectedTo(out iPinAVISplitterIn); DsError.ThrowExceptionForHR(hr); hr = iPinAVISplitterOut.Disconnect(); DsError.ThrowExceptionForHR(hr); hr = iPinAVISplitterIn.Disconnect(); DsError.ThrowExceptionForHR(hr); // Connect the avi splitter output to sample grabber IPin iPinSampleGrabberIn = DsFindPin.ByDirection(sampleGrabberFilter, PinDirection.Input, 0); hr = graphBuilder.Connect(iPinAVISplitterOut, iPinSampleGrabberIn); DsError.ThrowExceptionForHR(hr); } // Add the null renderer to the graph nullrenderer = new NullRenderer() as IBaseFilter; hr = graphBuilder.AddFilter(nullrenderer, "Null renderer"); DsError.ThrowExceptionForHR(hr); // Get the input pin of the null renderer IPin iPinNullRendererIn = DsFindPin.ByDirection(nullrenderer, PinDirection.Input, 0); // Connect the sample grabber to the null renderer hr = graphBuilder.Connect(iPinSampleGrabberOut, iPinNullRendererIn); DsError.ThrowExceptionForHR(hr); // Read and cache the image sizes SaveSizeInfo(sampleGrabber); this.GetFrameStepInterface(); } finally { } }
public static void RemoveFromGraph(IGraphBuilder graphBuilder) { IBaseFilter vob = null; using (Settings xmlreader = new MPSettings()) { string engineType = xmlreader.GetValueAsString("subtitles", "engine", "DirectVobSub"); XySubFilter = engineType.Equals("XySubFilter"); } if (!XySubFilter) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubAutoload, out vob); if (vob == null) { //Try the "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.DirectVobSubNormal, out vob); } } if (vob == null) { DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterAutoload, out vob); if (vob != null) { //remove the XySubFilter filter from the graph graphBuilder.RemoveFilter(vob); DirectShowUtil.ReleaseComObject(vob); vob = null; return; } //Try the XySubFilter "normal" filter then. DirectShowUtil.FindFilterByClassID(graphBuilder, ClassId.XySubFilterNormal, out vob); if (vob != null) { //remove the XySubFilter filter from the graph graphBuilder.RemoveFilter(vob); DirectShowUtil.ReleaseComObject(vob); vob = null; } return; } Log.Info("VideoPlayerVMR9: DirectVobSub in graph, removing..."); // Check where video inputs are connected IPin pinVideoIn = DsFindPin.ByDirection(vob, PinDirection.Input, 0); IPin pinVideoOut = DsFindPin.ByDirection(vob, PinDirection.Output, 0); //find directvobsub's video output pin source input pin IPin pinVideoTo = null; if (pinVideoOut != null) { pinVideoOut.ConnectedTo(out pinVideoTo); } //find directvobsub's video input pin source output pin IPin pinVideoFrom = null; if (pinVideoIn != null) { pinVideoIn.ConnectedTo(out pinVideoFrom); } int hr = 0; if (pinVideoFrom != null) { hr = pinVideoFrom.Disconnect(); if (hr != 0) { Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting source pin"); } } if (pinVideoTo != null) { hr = pinVideoTo.Disconnect(); if (hr != 0) { Log.Error("VideoPlayerVMR9: DirectVobSub failed disconnecting destination pin"); } } //remove the DirectVobSub filter from the graph graphBuilder.RemoveFilter(vob); DirectShowUtil.ReleaseComObject(vob); vob = null; //reconnect the source output pin to the vmr9/evr filter if (pinVideoFrom != null) { if (pinVideoTo != null) { hr = graphBuilder.Connect(pinVideoFrom, pinVideoTo); } //hr = graphBuilder.Render(pinVideoFrom); DirectShowUtil.ReleaseComObject(pinVideoFrom); pinVideoFrom = null; } if (pinVideoTo != null) { DirectShowUtil.ReleaseComObject(pinVideoTo); pinVideoTo = null; } if (pinVideoOut != null) { DirectShowUtil.ReleaseComObject(pinVideoOut); pinVideoOut = null; } if (pinVideoIn != null) { DirectShowUtil.ReleaseComObject(pinVideoIn); pinVideoIn = null; } if (hr != 0) { Log.Error("VideoPlayerVMR9: Could not connect video out to video renderer: {0}", hr); } else { Log.Debug("VideoPlayerVMR9: DirectVobSub graph rebuild finished"); } }
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 bool DisconnectPin(IGraphBuilder graphBuilder, IPin pin) { IPin other; int hr = pin.ConnectedTo(out other); bool allDisconnected = true; PinInfo info; pin.QueryPinInfo(out info); DsUtils.FreePinInfo(info); Log.Info("Disconnecting pin {0}", info.name); if (hr == 0 && other != null) { other.QueryPinInfo(out info); if (!DisconnectAllPins(graphBuilder, info.filter)) { allDisconnected = false; } hr = pin.Disconnect(); if (hr != 0) { allDisconnected = false; Log.Error("Error disconnecting: {0:x}", hr); } hr = other.Disconnect(); if (hr != 0) { allDisconnected = false; Log.Error("Error disconnecting other: {0:x}", hr); } DsUtils.FreePinInfo(info); ReleaseComObject(other); } else { Log.Info(" Not connected"); } return allDisconnected; }