protected virtual void InsertAudioFilter(IBaseFilter sourceFilter, string audioDecoder) { if (string.IsNullOrEmpty(audioDecoder)) { return; } // Set Audio Codec // Remove Pin var audioPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Audio"); IPin audioPinTo; if (audioPinFrom != null) { int hr = audioPinFrom.ConnectedTo(out audioPinTo); if (hr >= 0 && audioPinTo != null) { PinInfo pInfo; audioPinTo.QueryPinInfo(out pInfo); FilterInfo fInfo; pInfo.filter.QueryFilterInfo(out fInfo); DirectShowUtil.DisconnectAllPins(m_graph, pInfo.filter); m_graph.RemoveFilter(pInfo.filter); DsUtils.FreePinInfo(pInfo); Marshal.ReleaseComObject(fInfo.pGraph); Marshal.ReleaseComObject(audioPinTo); audioPinTo = null; } Marshal.ReleaseComObject(audioPinFrom); audioPinFrom = null; } DirectShowUtil.AddFilterToGraph(m_graph, audioDecoder, Guid.Empty); }
/// <summary> /// Opens the media by initializing the DirectShow graph /// </summary> protected virtual void OpenSource() { /* Make sure we clean up any remaining mess */ FreeResources(); if (m_sourceUri == null) { return; } string fileSource = m_sourceUri.OriginalString; if (string.IsNullOrEmpty(fileSource)) { return; } try { /* Creates the GraphBuilder COM object */ m_graph = new FilterGraphNoThread() as IGraphBuilder; if (m_graph == null) { throw new Exception("Could not create a graph"); } var filterGraph = m_graph as IFilterGraph2; if (filterGraph == null) { throw new Exception("Could not QueryInterface for the IFilterGraph2"); } IBaseFilter sourceFilter; int hr; //var file = System.IO.File.CreateText(@"M:\DirectShowLog.txt"); //filterGraph.SetLogFile((file.BaseStream as System.IO.FileStream).SafeFileHandle.DangerousGetHandle()); // Set LAV Splitter LAVSplitterSource reader = new LAVSplitterSource(); sourceFilter = reader as IBaseFilter; var objectWithSite = reader as IObjectWithSite; if (objectWithSite != null) { objectWithSite.SetSite(this); } hr = m_graph.AddFilter(sourceFilter, SplitterSource); DsError.ThrowExceptionForHR(hr); IFileSourceFilter interfaceFile = (IFileSourceFilter)sourceFilter; hr = interfaceFile.Load(fileSource, null); DsError.ThrowExceptionForHR(hr); // Set Video Codec // Remove Pin var videoPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Video"); IPin videoPinTo; if (videoPinFrom != null) { hr = videoPinFrom.ConnectedTo(out videoPinTo); if (hr >= 0 && videoPinTo != null) { PinInfo pInfo; videoPinTo.QueryPinInfo(out pInfo); FilterInfo fInfo; pInfo.filter.QueryFilterInfo(out fInfo); DirectShowUtil.DisconnectAllPins(m_graph, pInfo.filter); m_graph.RemoveFilter(pInfo.filter); DsUtils.FreePinInfo(pInfo); Marshal.ReleaseComObject(fInfo.pGraph); Marshal.ReleaseComObject(videoPinTo); videoPinTo = null; } Marshal.ReleaseComObject(videoPinFrom); videoPinFrom = null; } DirectShowUtil.AddFilterToGraph(m_graph, VideoDecoder, Guid.Empty); // Set Audio Codec // Remove Pin var audioPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Audio"); IPin audioPinTo; if (audioPinFrom != null) { hr = audioPinFrom.ConnectedTo(out audioPinTo); if (hr >= 0 && audioPinTo != null) { PinInfo pInfo; audioPinTo.QueryPinInfo(out pInfo); FilterInfo fInfo; pInfo.filter.QueryFilterInfo(out fInfo); DirectShowUtil.DisconnectAllPins(m_graph, pInfo.filter); m_graph.RemoveFilter(pInfo.filter); DsUtils.FreePinInfo(pInfo); Marshal.ReleaseComObject(fInfo.pGraph); Marshal.ReleaseComObject(audioPinTo); audioPinTo = null; } Marshal.ReleaseComObject(audioPinFrom); audioPinFrom = null; } DirectShowUtil.AddFilterToGraph(m_graph, AudioDecoder, Guid.Empty); /* Add our prefered audio renderer */ InsertAudioRenderer(AudioRenderer); IBaseFilter renderer = CreateVideoRenderer(VideoRenderer, m_graph, 2); /* We will want to enum all the pins on the source filter */ IEnumPins pinEnum; hr = sourceFilter.EnumPins(out pinEnum); DsError.ThrowExceptionForHR(hr); IntPtr fetched = IntPtr.Zero; IPin[] pins = { null }; /* Counter for how many pins successfully rendered */ int pinsRendered = 0; if (VideoRenderer == VideoRendererType.VideoMixingRenderer9) { var mixer = renderer as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetRGB; //mixer.SetMixingPrefs(dwPrefs); } } /* Test using FFDShow Video Decoder Filter * var ffdshow = new FFDShow() as IBaseFilter; * * if (ffdshow != null) * m_graph.AddFilter(ffdshow, "ffdshow"); */ /* Loop over each pin of the source filter */ while (pinEnum.Next(pins.Length, pins, fetched) == 0) { if (filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0) { pinsRendered++; } Marshal.ReleaseComObject(pins[0]); } Marshal.ReleaseComObject(pinEnum); Marshal.ReleaseComObject(sourceFilter); if (pinsRendered == 0) { throw new Exception("Could not render any streams from the source Uri"); } #if DEBUG /* Adds the GB to the ROT so we can view * it in graphedit */ m_dsRotEntry = new DsROTEntry(m_graph); #endif /* Configure the graph in the base class */ SetupFilterGraph(m_graph); HasVideo = true; /* Sets the NaturalVideoWidth/Height */ //SetNativePixelSizes(renderer); } catch (Exception ex) { /* This exection will happen usually if the media does * not exist or could not open due to not having the * proper filters installed */ FreeResources(); /* Fire our failed event */ InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); } InvokeMediaOpened(); }
private bool DoesItHaveVideo(string filename) { if (string.IsNullOrEmpty(filename)) { return(false); } bool result; IGraphBuilder temp_graph = new FilterGraphNoThread() as IGraphBuilder; try { if (temp_graph == null) { throw new WPFMediaKitException("Could not create a graph"); } var filterGraph = temp_graph as IFilterGraph2; if (filterGraph == null) { throw new WPFMediaKitException("Could not QueryInterface for the IFilterGraph2"); } IBaseFilter sourceFilter; int hr; sourceFilter = DirectShowUtil.AddFilterToGraph(temp_graph, SplitterSource, LAVFilterDirectory, Guid.Empty); if (sourceFilter == null) { throw new WPFMediaKitException("Could not add SplitterSource to graph."); } IFileSourceFilter interfaceFile = (IFileSourceFilter)sourceFilter; hr = interfaceFile.Load(filename, null); DsError.ThrowExceptionForHR(hr); // Set Video Codec // Remove Pin var videoPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Video"); IPin videoPinTo; if (videoPinFrom != null) { hr = videoPinFrom.ConnectedTo(out videoPinTo); if (hr >= 0 && videoPinTo != null) { PinInfo pInfo; videoPinTo.QueryPinInfo(out pInfo); FilterInfo fInfo; pInfo.filter.QueryFilterInfo(out fInfo); DirectShowUtil.DisconnectAllPins(temp_graph, pInfo.filter); temp_graph.RemoveFilter(pInfo.filter); DsUtils.FreePinInfo(pInfo); Marshal.ReleaseComObject(fInfo.pGraph); Marshal.ReleaseComObject(videoPinTo); videoPinTo = null; } Marshal.ReleaseComObject(videoPinFrom); videoPinFrom = null; result = true; } else { result = false; } DirectShowUtil.RemoveFilters(temp_graph, SplitterSource.Name); Marshal.FinalReleaseComObject(sourceFilter); } catch { result = false; } finally { Marshal.ReleaseComObject(temp_graph); } return(result); }
/// <summary> /// Opens the media by initializing the DirectShow graph /// </summary> protected virtual void OpenSource() { /* Make sure we clean up any remaining mess */ FreeResources(); string fileSource = FileSource; if (string.IsNullOrEmpty(fileSource)) { return; } try { /* Creates the GraphBuilder COM object */ m_graph = new FilterGraphNoThread() as IGraphBuilder; if (m_graph == null) { throw new WPFMediaKitException("Could not create a graph"); } var filterGraph = m_graph as IFilterGraph2; if (filterGraph == null) { throw new WPFMediaKitException("Could not QueryInterface for the IFilterGraph2"); } IBaseFilter sourceFilter; int hr; // Set LAV Splitter /* LAVSplitterSource reader = new LAVSplitterSource(); * sourceFilter = reader as IBaseFilter; * var objectWithSite = reader as IObjectWithSite; * if (objectWithSite != null) * { * objectWithSite.SetSite(this); * } * * * hr = m_graph.AddFilter(sourceFilter, SplitterSource); * DsError.ThrowExceptionForHR(hr);*/ sourceFilter = DirectShowUtil.AddFilterToGraph(m_graph, SplitterSource, Guid.Empty); if (sourceFilter == null) { throw new WPFMediaKitException("Could not add SplitterSource to graph."); } IFileSourceFilter interfaceFile = (IFileSourceFilter)sourceFilter; hr = interfaceFile.Load(fileSource, null); DsError.ThrowExceptionForHR(hr); // Set Video Codec // Remove Pin var videoPinFrom = DirectShowLib.DsFindPin.ByName(sourceFilter, "Video"); IPin videoPinTo; if (videoPinFrom != null) { hr = videoPinFrom.ConnectedTo(out videoPinTo); if (hr >= 0 && videoPinTo != null) { PinInfo pInfo; videoPinTo.QueryPinInfo(out pInfo); FilterInfo fInfo; pInfo.filter.QueryFilterInfo(out fInfo); DirectShowUtil.DisconnectAllPins(m_graph, pInfo.filter); m_graph.RemoveFilter(pInfo.filter); DsUtils.FreePinInfo(pInfo); Marshal.ReleaseComObject(fInfo.pGraph); Marshal.ReleaseComObject(videoPinTo); videoPinTo = null; } Marshal.ReleaseComObject(videoPinFrom); videoPinFrom = null; HasVideo = true; } else { HasVideo = false; } DirectShowUtil.AddFilterToGraph(m_graph, VideoDecoder, Guid.Empty); try { // use preffered audio filter InsertAudioFilter(sourceFilter, AudioDecoder); } catch (Exception ex) { // codecs misconfigured log.Error(ex, "Cannot add audio decoder: {0}", AudioDecoder); } // use prefered audio renderer try { InsertAudioRenderer(AudioRenderer); } catch (Exception ex) { log.Error(ex, "Cannot add audio render: {0}", AudioRenderer); } IBaseFilter renderer = CreateVideoRenderer(VideoRenderer, m_graph, 2); /* We will want to enum all the pins on the source filter */ IEnumPins pinEnum; hr = sourceFilter.EnumPins(out pinEnum); DsError.ThrowExceptionForHR(hr); IntPtr fetched = IntPtr.Zero; IPin[] pins = { null }; /* Counter for how many pins successfully rendered */ int pinsRendered = 0; if (VideoRenderer == VideoRendererType.VideoMixingRenderer9) { var mixer = renderer as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetRGB; //mixer.SetMixingPrefs(dwPrefs); } } /* Loop over each pin of the source filter */ while (pinEnum.Next(pins.Length, pins, fetched) == 0) { if (filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0) { pinsRendered++; } Marshal.ReleaseComObject(pins[0]); } Marshal.ReleaseComObject(pinEnum); Marshal.ReleaseComObject(sourceFilter); if (pinsRendered == 0) { throw new WPFMediaKitException("Could not render any streams from the source Uri"); } #if DEBUG /* Adds the GB to the ROT so we can view * it in graphedit */ m_dsRotEntry = new DsROTEntry(m_graph); #endif /* Configure the graph in the base class */ SetupFilterGraph(m_graph); } catch (Exception ex) { /* This exection will happen usually if the media does * not exist or could not open due to not having the * proper filters installed */ // Fallback try auto graph: var result = oldOpenSource(); if (!result) { FreeResources(); HasVideo = false; /* Fire our failed event */ InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); return; } } InvokeMediaOpened(); }
protected virtual void OpenSource() { /* Make sure we clean up any remaining mess */ FreeResources(); string fileSource = FileSource; if (string.IsNullOrEmpty(fileSource)) { return; } try { //lets get over with it right here HasVideo = DoesItHaveVideo(FileSource); GC.Collect(); GC.WaitForPendingFinalizers(); /* Creates the GraphBuilder COM object */ m_graph = new FilterGraphNoThread() as IGraphBuilder; if (m_graph == null) { throw new WPFMediaKitException("Could not create a graph"); } var filterGraph = m_graph as IFilterGraph2; if (filterGraph == null) { throw new WPFMediaKitException("Could not QueryInterface for the IFilterGraph2"); } IBaseFilter sourceFilter; int hr; // Set LAV Splitter /* LAVSplitterSource reader = new LAVSplitterSource(); * sourceFilter = reader as IBaseFilter; * var objectWithSite = reader as IObjectWithSite; * if (objectWithSite != null) * { * objectWithSite.SetSite(this); * } * * * hr = m_graph.AddFilter(sourceFilter, SplitterSource); * DsError.ThrowExceptionForHR(hr);*/ //we are using AsyncFileSource here, so that file will not be locked during preview sourceFilter = DirectShowUtil.AddFilterToGraph(m_graph, AsyncFileSource, LAVFilterDirectory, Guid.Empty); if (sourceFilter == null) { throw new WPFMediaKitException("Could not add SplitterSource to graph."); } IFileSourceFilter interfaceFile = (IFileSourceFilter)sourceFilter; hr = interfaceFile.Load(fileSource, null); DsError.ThrowExceptionForHR(hr); // we are going to need LavSpltter here, to connect AsyncFileSource with VideoDecoder DirectShowUtil.AddFilterToGraph(m_graph, Splitter, LAVFilterDirectory, Guid.Empty); DirectShowUtil.AddFilterToGraph(m_graph, VideoDecoder, LAVFilterDirectory, Guid.Empty); try { // use preffered audio filter InsertAudioFilter(sourceFilter, AudioDecoder); } catch (Exception ex) { // codecs misconfigured log.Error(ex, "Cannot add audio decoder: {0}", AudioDecoder); } // use prefered audio renderer try { InsertAudioRenderer(AudioRenderer); } catch (Exception ex) { log.Error(ex, "Cannot add audio render: {0}", AudioRenderer); } IBaseFilter renderer = CreateVideoRenderer(VideoRenderer, m_graph, 2); /* We will want to enum all the pins on the source filter */ IEnumPins pinEnum; hr = sourceFilter.EnumPins(out pinEnum); DsError.ThrowExceptionForHR(hr); IntPtr fetched = IntPtr.Zero; IPin[] pins = { null }; /* Counter for how many pins successfully rendered */ int pinsRendered = 0; if (VideoRenderer == VideoRendererType.VideoMixingRenderer9) { var mixer = renderer as IVMRMixerControl9; if (mixer != null) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetRGB; //mixer.SetMixingPrefs(dwPrefs); } } /* Loop over each pin of the source filter */ while (pinEnum.Next(pins.Length, pins, fetched) == 0) { if (filterGraph.RenderEx(pins[0], AMRenderExFlags.RenderToExistingRenderers, IntPtr.Zero) >= 0) { pinsRendered++; } Marshal.ReleaseComObject(pins[0]); } Marshal.ReleaseComObject(pinEnum); Marshal.ReleaseComObject(sourceFilter); if (pinsRendered == 0) { throw new WPFMediaKitException("Could not render any streams from the source Uri"); } #if DEBUG /* Adds the GB to the ROT so we can view * it in graphedit */ m_dsRotEntry = new DsROTEntry(m_graph); #endif /* Configure the graph in the base class */ SetupFilterGraph(m_graph); GetFrameStepInterface(); } catch (Exception ex) { /* This exection will happen usually if the media does * not exist or could not open due to not having the * proper filters installed */ // Fallback try auto graph: var result = oldOpenSource(); if (!result) { FreeResources(); HasVideo = false; /* Fire our failed event */ InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); return; } } InvokeMediaOpened(); }