/// <summary> /// Releases the capture device /// </summary> private void Release() { // Stop the thread _worker = null; // Clear the event if (_stopSignal != null) { _stopSignal.Close(); _stopSignal = null; } if (_graph != null) { _graph.Abort(); _graph.Disconnect(_sourceObject.GetPin(PinDirection.Output, 0)); _graph.Disconnect(_grabberObject.GetPin(PinDirection.Input, 0)); _graph.RemoveFilter(_sourceObject); _graph.RemoveFilter(_grabberObject); } // Clean up _graph = null; _sourceObject = null; _grabberObject = null; _grabber = null; _capGrabber = null; _control = null; }
private void TryRenderSubpicture(IGraphBuilder pGraphBuilder, IPin subpictureOutPin, IPin videoOutPin, IPin videoRendererInputPin) { var subpictureFilter = GetSubpictureFilter(pGraphBuilder); if (subpictureFilter == null) { throw new Exception(); } try { ConnectVideoToSubpictureFilter(pGraphBuilder, videoOutPin, subpictureFilter); ConnectSubpictureToSubpictureFilter(pGraphBuilder, subpictureOutPin, subpictureFilter); ConnectSubpictureFilterToRenderer(pGraphBuilder, subpictureFilter, videoRendererInputPin); CollectSubpictureStreamsInfo(); } catch { pGraphBuilder.Disconnect(videoRendererInputPin); pGraphBuilder.Disconnect(subpictureOutPin); pGraphBuilder.Disconnect(videoOutPin); throw; } finally { Marshal.FinalReleaseComObject(subpictureFilter); } }
/// <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> void RemoveDownstream(IBaseFilter filter) { // Get a pin enumerator off the filter var hr = filter.EnumPins(out IEnumPins pinEnum); if (pinEnum == null) { return; } pinEnum.Reset(); if (hr == 0) { // Loop through each pin var pins = new IPin[1]; do { // Get the next pin hr = pinEnum.Next(1, pins, out int _); if (hr == 0 && pins[0] != null) { // Get the pin it is connected to pins[0].ConnectedTo(out IPin pinTo); if (pinTo != null) { // Is this an input pin? hr = pinTo.QueryPinInfo(out PinInfo info); if (hr == 0 && info.dir == PinDirection.Input) { // Recurse down this branch RemoveDownstream(info.filter); // Disconnect _graphBuilder.Disconnect(pinTo); _graphBuilder.Disconnect(pins[0]); // Remove this filter // but don't remove the video or audio compressors if (info.filter != _videoCompressorFilter) { _graphBuilder.RemoveFilter(info.filter); } } Marshal.ReleaseComObject(info.filter); Marshal.ReleaseComObject(pinTo); } Marshal.ReleaseComObject(pins[0]); } } while (hr == 0); Marshal.ReleaseComObject(pinEnum); } }
protected void removeDownstream(IBaseFilter filter, bool removeFirstFilter) { // 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]; int f; do { // Get the next pin hr = pinEnum.Next(1, pins, out 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; } }
public static void Disconnect(IGraphBuilder pGraphBuilder, IPin pPin) { IPin pInputPin = null; if (pPin.ConnectedTo(out pInputPin) == DsHlp.S_OK) { pGraphBuilder.Disconnect(pInputPin); Marshal.ReleaseComObject(pInputPin); } pGraphBuilder.Disconnect(pPin); }
public void Disconnect(IPin ipin) { try { int hr = graphBuilder.Disconnect(ipin); DsError.ThrowExceptionForHR(hr); } catch (COMException e) { ShowCOMException(e, "Error disconnecting pin"); } catch { //MessageBox.Show(e.Message, "Error disconnecting pin"); } }
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 IBaseFilter AddToGraph(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 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 filter not found! You need to install VSFilter"); return null; } else { 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; }