public void Dispose() { GC.SuppressFinalize(this); Stop(); if (m_pController != null) { m_pController.BridgeGraphs(null, null); Marshal.ReleaseComObject(m_pController); m_pController = null; } foreach (ClipEntry ce in m_Clips) { ce.Dispose(); } m_Clips.Clear(); if (m_pRenderGraph != null) { Marshal.ReleaseComObject(m_pRenderGraph); m_pRenderGraph = null; } if (m_pRenderGraphSourceFilter != null) { Marshal.ReleaseComObject(m_pRenderGraphSourceFilter); m_pRenderGraphSourceFilter = null; } }
public ClipPlayer(IntPtr hwnd, int msgSegment, int msgEvent) { m_bLoop = false; m_tDuration = 0; m_tStartPosition = 0; m_bActive = false; m_hwndApp = hwnd; m_msgEvent = msgEvent; m_msgSegment = msgSegment; m_pPlayNext = -1; m_Clips = new ArrayList(5); m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(hwnd, msgSegment); // we use a video and an audio stream, // options: //don't allow compressed in source graphs, //don't discard when not connected m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.AddStream(false, eFormatType.Uncompressed, false); // increase buffering at the join, so that audio does not run out m_pController.SetBufferMinimum(200); m_itCurrent = m_Clips.Count; }
/// <summary> /// Performs the network connection /// </summary> public void Connect() { try { StatusError = null; this.Status = NetworkSourceStatus.Connecting; Debug.WriteLine("LTNetworkSource add filters"); AddLTNetSource(); AddLTNetDemux(); this.Status = NetworkSourceStatus.Buffering; Debug.WriteLine("LTNetworkSource.DoConnect"); DoConnect(ltsfUrl); FilterGraphTools.ConnectFilters(graph, netSource, "Output", netDemux, "Input 01", false); Debug.WriteLine("LTNetworkSource create controller"); controller = (IGMFBridgeController) new GMFBridgeControllerClass(); Debug.WriteLine("LTNetworkSource.RenderNetDemux"); RenderNetDemux(); Debug.WriteLine("LTNetworkSource done constructing"); this.Status = NetworkSourceStatus.Connected; } catch (Exception ex) { StatusError = ex; this.Status = NetworkSourceStatus.Faulted; throw ex; } }
public ClipPlayer(IntPtr hwnd, int msgSegment, int msgEvent) { m_bLoop = false; m_tDuration = 0; m_tStartPosition = 0; m_bActive = false; m_hwndApp = hwnd; m_msgEvent = msgEvent; m_msgSegment = msgSegment; m_pPlayNext = -1; m_Clips = new ArrayList(5); m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(hwnd, msgSegment); // we use a video and an audio stream, // options: //don't allow compressed in source graphs, //don't discard when not connected m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.AddStream(false, eFormatType.Uncompressed, false); // increase buffering at the join, so that audio does not run out m_pController.SetBufferMinimum(200); m_itCurrent = m_Clips.Count; }
public int AddClip(string path, out ClipEntry pClip) { int it = m_Clips.Count; pClip = new ClipEntry(); m_Clips.Add(pClip); int hr = pClip.Create(m_pController, path); // if we expect both audio and video, then all clips // must have both audio and video. // If the first clip is video only, then switch // to video-only automatically if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) { // new controller, different options (only one video stream) if (m_pController != null) { Marshal.ReleaseComObject(m_pController); m_pController = null; } m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(m_hwndApp, m_msgSegment); m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.SetBufferMinimum(200); // try again hr = pClip.Create(m_pController, path); } if (hr >= 0) { pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); // if this is the first clip, create the render graph if (m_Clips.Count == 1) { m_pRenderGraph = new FilterGraph() as IGraphBuilder; hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); if (hr >= 0 && m_hwndApp != IntPtr.Zero) { IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; if (pME != null) { pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); } } } } else { pClip.Dispose(); m_Clips.RemoveAt(it); } return(hr); }
/// <summary> /// The release select members. /// </summary> private void ReleaseSelectMembers() { if (this.m_rot1 != null) { this.m_rot1.Dispose(); this.m_rot1 = null; } if (this.videoPanel != null) { this.videoPanel.Resize -= this.videoPanel_Resize; } if (this.gmfBridgeController != null) { Marshal.ReleaseComObject(this.gmfBridgeController); this.gmfBridgeController = null; } if (this.m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(this.m_pSourceGraphSinkFilter); this.m_pSourceGraphSinkFilter = null; } if (this.m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(this.m_pSourceGraphSinkFilter); this.m_pSourceGraphSinkFilter = null; } if (this.m_pCapOutput != null) { Marshal.ReleaseComObject(this.m_pCapOutput); this.m_pCapOutput = null; } if (this.sourceFilterGraph != null) { Marshal.ReleaseComObject(this.sourceFilterGraph); this.sourceFilterGraph = null; } }
public int Create(IGMFBridgeController pController, string path) { m_bPrimed = false; m_pGraph = new FilterGraph() as IGraphBuilder; int hr = pController.CreateSourceGraph(path, m_pGraph, out m_pSinkFilter); m_strName = path.Substring(path.LastIndexOf('\\') + 1); if (hr < 0) { if (m_pGraph != null) { Marshal.ReleaseComObject(m_pGraph); m_pGraph = null; } } return(hr); }
/// <summary> /// Builds the actual DirectShow graph and performs the connection to the URL specified in the constructor. /// </summary> public void Setup() { lock (instanceMutex) { int hr; // An exception is thrown if cast fail //create playback graph _graphBuilder = (IGraphBuilder) new FilterGraph(); _captureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); _mediaControl = (IMediaControl)_graphBuilder; // Attach the filter graph to the capture graph hr = _captureGraphBuilder.SetFiltergraph(_graphBuilder); DsError.ThrowExceptionForHR(hr); //create bridge controller _bridgeController = new GMFBridgeControllerClass(); //add a video stream to the bridge //1 = Video stream 0 = Audio stream, format type, 1 = dispose stream going into disconnected sink 0 = buffer stream going into disconnected sink _bridgeController.AddStream(1, eFormatType.eAny, 1); AddLeadNetSrc(); AddLeadNetDemux(); ConnectFilters(_graphBuilder, _netSrc, "Output", _netDmx, "Input 01", true); //insert Infinite Pin Tee into playback graph _infPinTee = AddFilterByName(_graphBuilder, FilterCategory.LegacyAmFilterCategory, "Infinite Pin Tee Filter"); //add a bridge sink to the playback graph _bridgeSink = (IBaseFilter)_bridgeController.InsertSinkFilter(_graphBuilder); //finish building playback/source graph, so we can negotiate data types on bridge AddVideoRender(); RenderNetDemux(); _telemetryTimer = new System.Threading.Timer(new System.Threading.TimerCallback(TelemetryTimer_Tick)); } }
// Release all the members of the source graph private void ReleaseSelectMembers() { if (m_rot1 != null) { m_rot1.Dispose(); m_rot1 = null; } if (m_pBridge != null) { Marshal.ReleaseComObject(m_pBridge); m_pBridge = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } if (m_pCapOutput != null) { Marshal.ReleaseComObject(m_pCapOutput); m_pCapOutput = null; } if (m_pSourceGraph != null) { Marshal.ReleaseComObject(m_pSourceGraph); m_pSourceGraph = null; } }
public void Dispose() { GC.SuppressFinalize(this); Stop(); if (m_pController != null) { m_pController.BridgeGraphs(null, null); Marshal.ReleaseComObject(m_pController); m_pController = null; } foreach(ClipEntry ce in m_Clips) { ce.Dispose(); } m_Clips.Clear(); if (m_pRenderGraph != null) { Marshal.ReleaseComObject(m_pRenderGraph); m_pRenderGraph = null; } if (m_pRenderGraphSourceFilter != null) { Marshal.ReleaseComObject(m_pRenderGraphSourceFilter); m_pRenderGraphSourceFilter = null; } }
SelectDevice(DsDevice dev, IntPtr hwnd) { int hr; IBaseFilter pfDevice = null; ICaptureGraphBuilder2 pBuilder = null; // release any leftovers ReleaseSelectMembers(); try { // create source graph and add sink filter m_pSourceGraph = (IGraphBuilder) new FilterGraph(); m_rot1 = new DsROTEntry(m_pSourceGraph); m_pBridge = (IGMFBridgeController) new GMFBridgeController(); // init to video-only, in discard mode (ie when source graph // is running but not connected, buffers are discarded at the bridge) hr = m_pBridge.AddStream(true, eFormatType.MuxInputs, true); DsError.ThrowExceptionForHR(hr); // Add the requested device hr = ((IFilterGraph2)m_pSourceGraph).AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out pfDevice); DsError.ThrowExceptionForHR(hr); // Add the sink filter to the source graph hr = m_pBridge.InsertSinkFilter(m_pSourceGraph, out m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); // use capture graph builder to render preview pBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); // Init the CaptureGraphBuilder2 hr = pBuilder.SetFiltergraph(m_pSourceGraph); DsError.ThrowExceptionForHR(hr); // Connect the filters together to allow preview hr = pBuilder.RenderStream(PinCategory.Preview, MediaType.Video, pfDevice, null, null); DsError.ThrowExceptionForHR(hr); // connect capture output to the pseudo-sink filter, // where it will be discarded until required hr = pBuilder.RenderStream(PinCategory.Capture, MediaType.Video, pfDevice, null, m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); // turn off capture stream if possible except when capturing hr = pBuilder.FindPin(pfDevice, PinDirection.Output, PinCategory.Capture, MediaType.Video, false, 0, out m_pCapOutput); if (hr >= 0) { IAMStreamControl pSC = (IAMStreamControl)m_pCapOutput; pSC.StartAt(NEVER, 0); // Ignore any error } ConfigureVideo(hwnd); IMediaControl pMC = (IMediaControl)m_pSourceGraph; hr = pMC.Run(); DsError.ThrowExceptionForHR(hr); // If we made it here, the device is selected m_DeviceSelected = true; } catch { ReleaseSelectMembers(); throw; } finally { if (pBuilder != null) { Marshal.ReleaseComObject(pBuilder); } if (pfDevice != null) { Marshal.ReleaseComObject(pfDevice); } } }
protected virtual void Dispose(bool disposing) { if (disposing) { // get rid of managed resources } // get rid of unmanaged resources lock (instanceMutex) { //remove event handlers TelemetryUpdate = null; PropertyChanged = null; Complete = null; //detach from HWND DetachControl(); if (_netSrc != null) { Marshal.FinalReleaseComObject(_netSrc); _netSrc = null; } if (_decoderFilter != null) { Marshal.FinalReleaseComObject(_decoderFilter); _decoderFilter = null; } if (_telemetryTimer != null) { _telemetryTimer.Dispose(); _telemetryTimer = null; } if (_windowlessControl != null) { Marshal.FinalReleaseComObject(_windowlessControl); _windowlessControl = null; } if (_videoRender != null) { Marshal.FinalReleaseComObject(_videoRender); _videoRender = null; } //recording graph Disposal if (_infPinTee != null) { Marshal.FinalReleaseComObject(_infPinTee); _infPinTee = null; } if (_fileSink != null) { Marshal.FinalReleaseComObject(_fileSink); _fileSink = null; } if (_bridgeSink != null) { Marshal.FinalReleaseComObject(_bridgeSink); _bridgeSink = null; } if (_bridgeSource != null) { Marshal.FinalReleaseComObject(_bridgeSource); _bridgeSource = null; } if (_bridgeController != null) { Marshal.FinalReleaseComObject(_bridgeController); _bridgeController = null; } if (_fileSinkMediaControl != null) { Marshal.FinalReleaseComObject(_fileSinkMediaControl); _fileSinkMediaControl = null; } if (_fileSinkCaptureGraphBuilder != null) { Marshal.FinalReleaseComObject(_fileSinkCaptureGraphBuilder); _fileSinkCaptureGraphBuilder = null; } if (_fileSinkGraphBuilder != null) { Marshal.FinalReleaseComObject(_fileSinkGraphBuilder); _fileSinkGraphBuilder = null; } if (_fileSinkFilter != null) { Marshal.FinalReleaseComObject(_fileSinkFilter); _fileSinkFilter = null; } if (_muxer != null) { Marshal.FinalReleaseComObject(_muxer); _muxer = null; } if (_captureGraphBuilder != null) { Marshal.FinalReleaseComObject(_captureGraphBuilder); _captureGraphBuilder = null; } if (_graphBuilder != null) { Marshal.FinalReleaseComObject(_graphBuilder); //TODO race on RCW cleanup during app quit _graphBuilder = null; } } }
/// <summary> /// Destroys the DirectShow graph and releases all resources /// </summary> public void Dispose() { lock (instanceMutex) { GC.SuppressFinalize(this); //remove event handlers PropertyChanged = null; Complete = null; TelemetryUpdate = null; //detach from HWND DetachControl(); if (_netSrc != null) { Marshal.ReleaseComObject(_netSrc); Marshal.ReleaseComObject(_netSrc); Marshal.ReleaseComObject(_netSrc); Marshal.ReleaseComObject(_netSrc); _netSrc = null; } if (_decoderFilter != null) { Marshal.ReleaseComObject(_decoderFilter); _decoderFilter = null; } if (_telemetryTimer != null) { _telemetryTimer.Dispose(); _telemetryTimer = null; } if (_netDmx != null) { Marshal.ReleaseComObject(_netDmx); _netDmx = null; _lmNetDmx = null; } if (_windowlessControl != null) { Marshal.ReleaseComObject(_windowlessControl); _windowlessControl = null; } if (_videoRender != null) { Marshal.ReleaseComObject(_videoRender); _videoRender = null; } //recording graph Disposal if (_infPinTee != null) { Marshal.ReleaseComObject(_infPinTee); _infPinTee = null; } if (_fileSink != null) { Marshal.ReleaseComObject(_fileSink); _fileSink = null; } if (_bridgeSink != null) { Marshal.ReleaseComObject(_bridgeSink); _bridgeSink = null; } if (_bridgeSource != null) { Marshal.ReleaseComObject(_bridgeSource); _bridgeSource = null; } if (_bridgeController != null) { Marshal.ReleaseComObject(_bridgeController); _bridgeController = null; } if (_fileSinkMediaControl != null) { Marshal.ReleaseComObject(_fileSinkMediaControl); _fileSinkMediaControl = null; } if (_fileSinkCaptureGraphBuilder != null) { Marshal.ReleaseComObject(_fileSinkCaptureGraphBuilder); _fileSinkCaptureGraphBuilder = null; } if (_fileSinkGraphBuilder != null) { Marshal.ReleaseComObject(_fileSinkGraphBuilder); _fileSinkGraphBuilder = null; } if (_fileSinkFilter != null) { Marshal.ReleaseComObject(_fileSinkFilter); _fileSinkFilter = null; } if (_muxer != null) { Marshal.ReleaseComObject(_muxer); _muxer = null; } if (_captureGraphBuilder != null) { Marshal.ReleaseComObject(_captureGraphBuilder); _captureGraphBuilder = null; } if (_graphBuilder != null) { Marshal.ReleaseComObject(_graphBuilder); //TODO race on RCW cleanup during app quit _graphBuilder = null; } } }
/// <summary> /// Configures the DirectShow graph to play the selected video capture /// device with the selected parameters /// </summary> private void SetupGraph() { /* Clean up any messes left behind */ FreeResources(); try { logger.Info("Graph Setup"); /* Create a new graph */ m_pBridge = (IGMFBridgeController)new GMFBridgeController(); int hr = m_pBridge.AddStream(true, eFormatType.MuxInputs, true); DsError.ThrowExceptionForHR(hr); m_graph = (IGraphBuilder)new FilterGraphNoThread(); #if DEBUG m_rotEntry = new DsROTEntry(m_graph); #endif /* Create a capture graph builder to help * with rendering a capture graph */ var graphBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); hr = m_pBridge.InsertSinkFilter(m_graph, out m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); /* Set our filter graph to the capture graph */ logger.Info("VideoCaptureSource:" + VideoCaptureSource); if (VideoCaptureDevice != null) { logger.Info("VideoCaptureDevice.DevicePath:" + VideoCaptureDevice.DevicePath); } /* Add our capture device source to the graph */ if (m_videoCaptureSourceChanged) { m_captureDevice = AddFilterByName(m_graph, FilterCategory.VideoInputDevice, VideoCaptureSource); m_videoCaptureSourceChanged = false; } else if (m_videoCaptureDeviceChanged) { m_captureDevice = AddFilterByDevicePath(m_graph, FilterCategory.VideoInputDevice, VideoCaptureDevice.DevicePath); m_videoCaptureDeviceChanged = false; } /* If we have a null capture device, we have an issue */ if (m_captureDevice == null) throw new Exception(string.Format("Capture device {0} not found or could not be created", VideoCaptureSource)); object crossbar; var a = graphBuilder.FindInterface(null, null, m_captureDevice as IBaseFilter, typeof(IAMCrossbar).GUID, out crossbar); if(UseYuv && !EnableSampleGrabbing) { /* Configure the video output pin with our parameters and if it fails * then just use the default media subtype*/ if(!SetVideoCaptureParameters(graphBuilder, m_captureDevice, MediaSubType.YUY2)) SetVideoCaptureParameters(graphBuilder, m_captureDevice, Guid.Empty); } else /* Configure the video output pin with our parameters */ SetVideoCaptureParameters(graphBuilder, m_captureDevice, new Guid("73646976-0000-0010-8000-00AA00389B71")); var rendererType = VideoRendererType.VideoMixingRenderer9; /* Creates a video renderer and register the allocator with the base class */ m_renderer = CreateVideoRenderer(rendererType, m_graph, 1); if (rendererType == VideoRendererType.VideoMixingRenderer9) { var mixer = m_renderer as IVMRMixerControl9; if (mixer != null && !EnableSampleGrabbing && UseYuv) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; /* Prefer YUV */ mixer.SetMixingPrefs(dwPrefs); } } if (EnableSampleGrabbing) { m_sampleGrabber = (ISampleGrabber)new SampleGrabber(); SetupSampleGrabber(m_sampleGrabber); hr = m_graph.AddFilter(m_sampleGrabber as IBaseFilter, "SampleGrabber"); DsError.ThrowExceptionForHR(hr); } hr = graphBuilder.SetFiltergraph(m_graph); DsError.ThrowExceptionForHR(hr); IBaseFilter mux = null; IFileSinkFilter sink = null; if (!string.IsNullOrEmpty(this.fileName)) { } hr = graphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, m_captureDevice, null, m_renderer); DsError.ThrowExceptionForHR(hr); hr = graphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, m_captureDevice, null, m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); hr = graphBuilder.FindPin(m_captureDevice, PinDirection.Output, PinCategory.Capture, MediaType.Video, false, 0, out m_pCapOutput); if (hr >= 0) { IAMStreamControlBridge pSC = (IAMStreamControlBridge)m_pCapOutput; pSC.StartAt(NEVER, 0); // Ignore any error } /* Register the filter graph * with the base classes */ SetupFilterGraph(m_graph); /* Sets the NaturalVideoWidth/Height */ SetNativePixelSizes(m_renderer); HasVideo = true; /* Make sure we Release() this COM reference */ if (mux != null) { Marshal.ReleaseComObject(mux); } if (sink != null) { Marshal.ReleaseComObject(sink); } Marshal.ReleaseComObject(graphBuilder); } catch (Exception ex) { /* Something got fuct up */ FreeResources(); InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); } /* Success */ InvokeMediaOpened(); }
// Specify a device, and a window to draw the preview in public void SelectDevice(DsDevice dev, IntPtr hwnd) { int hr; IBaseFilter pfDevice = null; ICaptureGraphBuilder2 pBuilder = null; // release any leftovers ReleaseSelectMembers(); try { // create source graph and add sink filter m_pSourceGraph = (IGraphBuilder)new FilterGraph(); m_rot1 = new DsROTEntry(m_pSourceGraph); m_pBridge = (IGMFBridgeController)new GMFBridgeController(); // init to video-only, in discard mode (ie when source graph // is running but not connected, buffers are discarded at the bridge) hr = m_pBridge.AddStream(true, eFormatType.MuxInputs, true); DsError.ThrowExceptionForHR(hr); // Add the requested device hr = ((IFilterGraph2)m_pSourceGraph).AddSourceFilterForMoniker(dev.Mon, null, dev.Name, out pfDevice); DsError.ThrowExceptionForHR(hr); // Add the sink filter to the source graph hr = m_pBridge.InsertSinkFilter(m_pSourceGraph, out m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); // use capture graph builder to render preview pBuilder = (ICaptureGraphBuilder2)new CaptureGraphBuilder2(); // Init the CaptureGraphBuilder2 hr = pBuilder.SetFiltergraph(m_pSourceGraph); DsError.ThrowExceptionForHR(hr); // Connect the filters together to allow preview hr = pBuilder.RenderStream(PinCategory.Preview, MediaType.Video, pfDevice, null, null); DsError.ThrowExceptionForHR(hr); // connect capture output to the pseudo-sink filter, // where it will be discarded until required hr = pBuilder.RenderStream(PinCategory.Capture, MediaType.Video, pfDevice, null, m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); // turn off capture stream if possible except when capturing hr = pBuilder.FindPin(pfDevice, PinDirection.Output, PinCategory.Capture, MediaType.Video, false, 0, out m_pCapOutput); if (hr >= 0) { IAMStreamControl pSC = (IAMStreamControl)m_pCapOutput; pSC.StartAt(NEVER, 0); // Ignore any error } ConfigureVideo(hwnd); IMediaControl pMC = (IMediaControl)m_pSourceGraph; hr = pMC.Run(); DsError.ThrowExceptionForHR(hr); // If we made it here, the device is selected m_DeviceSelected = true; } catch { ReleaseSelectMembers(); throw; } finally { if (pBuilder != null) { Marshal.ReleaseComObject(pBuilder); } if (pfDevice != null) { Marshal.ReleaseComObject(pfDevice); } } }
public int Create(IGMFBridgeController pController, string path) { m_bPrimed = false; m_pGraph = new FilterGraph() as IGraphBuilder; int hr = pController.CreateSourceGraph(path, m_pGraph, out m_pSinkFilter); m_strName = path.Substring(path.LastIndexOf('\\')+1); if (hr < 0) { if (m_pGraph != null) { Marshal.ReleaseComObject(m_pGraph); m_pGraph = null; } } return hr; }
/// <summary> /// Configures the DirectShow graph to play the selected video capture /// device with the selected parameters /// </summary> private void SetupGraph() { /* Clean up any messes left behind */ FreeResources(); try { logger.Info("Graph Setup"); /* Create a new graph */ m_pBridge = (IGMFBridgeController) new GMFBridgeController(); int hr = m_pBridge.AddStream(true, eFormatType.MuxInputs, true); DsError.ThrowExceptionForHR(hr); m_graph = (IGraphBuilder) new FilterGraphNoThread(); #if DEBUG m_rotEntry = new DsROTEntry(m_graph); #endif /* Create a capture graph builder to help * with rendering a capture graph */ var graphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); hr = m_pBridge.InsertSinkFilter(m_graph, out m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); /* Set our filter graph to the capture graph */ logger.Info("VideoCaptureSource:" + VideoCaptureSource); if (VideoCaptureDevice != null) { logger.Info("VideoCaptureDevice.DevicePath:" + VideoCaptureDevice.DevicePath); } /* Add our capture device source to the graph */ if (m_videoCaptureSourceChanged) { m_captureDevice = AddFilterByName(m_graph, FilterCategory.VideoInputDevice, VideoCaptureSource); m_videoCaptureSourceChanged = false; } else if (m_videoCaptureDeviceChanged) { m_captureDevice = AddFilterByDevicePath(m_graph, FilterCategory.VideoInputDevice, VideoCaptureDevice.DevicePath); m_videoCaptureDeviceChanged = false; } /* If we have a null capture device, we have an issue */ if (m_captureDevice == null) { throw new Exception(string.Format("Capture device {0} not found or could not be created", VideoCaptureSource)); } object crossbar; var a = graphBuilder.FindInterface(null, null, m_captureDevice as IBaseFilter, typeof(IAMCrossbar).GUID, out crossbar); if (UseYuv && !EnableSampleGrabbing) { /* Configure the video output pin with our parameters and if it fails * then just use the default media subtype*/ if (!SetVideoCaptureParameters(graphBuilder, m_captureDevice, MediaSubType.YUY2)) { SetVideoCaptureParameters(graphBuilder, m_captureDevice, Guid.Empty); } } else { /* Configure the video output pin with our parameters */ SetVideoCaptureParameters(graphBuilder, m_captureDevice, new Guid("73646976-0000-0010-8000-00AA00389B71")); } var rendererType = VideoRendererType.VideoMixingRenderer9; /* Creates a video renderer and register the allocator with the base class */ m_renderer = CreateVideoRenderer(rendererType, m_graph, 1); if (rendererType == VideoRendererType.VideoMixingRenderer9) { var mixer = m_renderer as IVMRMixerControl9; if (mixer != null && !EnableSampleGrabbing && UseYuv) { VMR9MixerPrefs dwPrefs; mixer.GetMixingPrefs(out dwPrefs); dwPrefs &= ~VMR9MixerPrefs.RenderTargetMask; dwPrefs |= VMR9MixerPrefs.RenderTargetYUV; /* Prefer YUV */ mixer.SetMixingPrefs(dwPrefs); } } if (EnableSampleGrabbing) { m_sampleGrabber = (ISampleGrabber) new SampleGrabber(); SetupSampleGrabber(m_sampleGrabber); hr = m_graph.AddFilter(m_sampleGrabber as IBaseFilter, "SampleGrabber"); DsError.ThrowExceptionForHR(hr); } hr = graphBuilder.SetFiltergraph(m_graph); DsError.ThrowExceptionForHR(hr); IBaseFilter mux = null; IFileSinkFilter sink = null; if (!string.IsNullOrEmpty(this.fileName)) { } hr = graphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, m_captureDevice, null, m_renderer); DsError.ThrowExceptionForHR(hr); hr = graphBuilder.RenderStream(PinCategory.Capture, MediaType.Video, m_captureDevice, null, m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); hr = graphBuilder.FindPin(m_captureDevice, PinDirection.Output, PinCategory.Capture, MediaType.Video, false, 0, out m_pCapOutput); if (hr >= 0) { IAMStreamControlBridge pSC = (IAMStreamControlBridge)m_pCapOutput; pSC.StartAt(NEVER, 0); // Ignore any error } /* Register the filter graph * with the base classes */ SetupFilterGraph(m_graph); /* Sets the NaturalVideoWidth/Height */ SetNativePixelSizes(m_renderer); HasVideo = true; /* Make sure we Release() this COM reference */ if (mux != null) { Marshal.ReleaseComObject(mux); } if (sink != null) { Marshal.ReleaseComObject(sink); } Marshal.ReleaseComObject(graphBuilder); } catch (Exception ex) { /* Something got fuct up */ FreeResources(); InvokeMediaFailed(new MediaFailedEventArgs(ex.Message, ex)); } /* Success */ InvokeMediaOpened(); }
protected override void FreeResources() { /* We run the StopInternal() to avoid any * Dispatcher VeryifyAccess() issues */ StopInternal(); /* Let's clean up the base * class's stuff first */ base.FreeResources(); #if DEBUG if (m_rotEntry != null) { m_rotEntry.Dispose(); } m_rotEntry = null; #endif if (m_videoFrame != null) { m_videoFrame.Dispose(); m_videoFrame = null; } if (m_renderer != null) { Marshal.FinalReleaseComObject(m_renderer); m_renderer = null; } if (m_captureDevice != null) { Marshal.FinalReleaseComObject(m_captureDevice); m_captureDevice = null; } if (m_sampleGrabber != null) { Marshal.FinalReleaseComObject(m_sampleGrabber); m_sampleGrabber = null; } if (m_graph != null) { Marshal.FinalReleaseComObject(m_graph); m_graph = null; InvokeMediaClosed(new EventArgs()); } if (m_pBridge != null) { Marshal.ReleaseComObject(m_pBridge); m_pBridge = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } }
// Specify a device, and a window to draw the preview in /// <summary> /// The select device. /// </summary> /// <param name="videoInputDevice"> /// The video input device. /// </param> /// <param name="panel"> /// The panel. /// </param> public void SelectDevice(DsDevice videoInputDevice, Panel panel) { int hr; IBaseFilter inputDeviceFilter = null; ICaptureGraphBuilder2 sourceCaptureGraphBuilder = null; this.ReleaseSelectMembers(); this.videoPanel = panel; this.videoPanel.Resize += this.videoPanel_Resize; // release any leftovers try { // create source graph and add sink filter this.sourceFilterGraph = (IGraphBuilder) new FilterGraph(); this.m_rot1 = new DsROTEntry(this.sourceFilterGraph); this.gmfBridgeController = (IGMFBridgeController) new GMFBridgeController(); // init to video-only, in discard mode (ie when source graph // is running but not connected, buffers are discarded at the bridge) hr = this.gmfBridgeController.AddStream(true, eFormatType.MuxInputs, true); DsError.ThrowExceptionForHR(hr); // Add the requested device hr = ((IFilterGraph2)this.sourceFilterGraph).AddSourceFilterForMoniker( videoInputDevice.Mon, null, videoInputDevice.Name, out inputDeviceFilter); DsError.ThrowExceptionForHR(hr); // Add the sink filter to the source graph hr = this.gmfBridgeController.InsertSinkFilter(this.sourceFilterGraph, out this.m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); // use capture graph builder to render preview sourceCaptureGraphBuilder = (ICaptureGraphBuilder2) new CaptureGraphBuilder2(); // Init the CaptureGraphBuilder2 hr = sourceCaptureGraphBuilder.SetFiltergraph(this.sourceFilterGraph); DsError.ThrowExceptionForHR(hr); // Connect the filters together to allow preview hr = sourceCaptureGraphBuilder.RenderStream(PinCategory.Preview, MediaType.Video, inputDeviceFilter, null, null); DsError.ThrowExceptionForHR(hr); // connect capture output to the pseudo-sink filter, // where it will be discarded until required hr = sourceCaptureGraphBuilder.RenderStream( PinCategory.Capture, MediaType.Video, inputDeviceFilter, null, this.m_pSourceGraphSinkFilter); DsError.ThrowExceptionForHR(hr); // turn off capture stream if possible except when capturing hr = sourceCaptureGraphBuilder.FindPin( inputDeviceFilter, PinDirection.Output, PinCategory.Capture, MediaType.Video, false, 0, out this.m_pCapOutput); if (hr >= 0) { var pSC = (IAMStreamControl)this.m_pCapOutput; pSC.StartAt(NEVER, 0); // Ignore any error } this.ConfigureVideo(); var pMC = (IMediaControl)this.sourceFilterGraph; hr = pMC.Run(); DsError.ThrowExceptionForHR(hr); // If we made it here, the device is selected this.m_DeviceSelected = true; } catch (Exception ex) { ErrorLogger.ProcessException(ex, true); this.ReleaseSelectMembers(); } finally { if (sourceCaptureGraphBuilder != null) { Marshal.ReleaseComObject(sourceCaptureGraphBuilder); } if (inputDeviceFilter != null) { Marshal.ReleaseComObject(inputDeviceFilter); } } }
public int AddClip(string path, out ClipEntry pClip) { int it = m_Clips.Count; pClip = new ClipEntry(); m_Clips.Add(pClip); int hr = pClip.Create(m_pController, path); // if we expect both audio and video, then all clips // must have both audio and video. // If the first clip is video only, then switch // to video-only automatically if ((hr == VFW_E_UNSUPPORTED_AUDIO) && (m_Clips.Count == 1)) { // new controller, different options (only one video stream) if (m_pController != null) { Marshal.ReleaseComObject(m_pController); m_pController = null; } m_pController = new GMFBridgeController() as IGMFBridgeController; m_pController.SetNotify(m_hwndApp, m_msgSegment); m_pController.AddStream(true, eFormatType.Uncompressed, false); m_pController.SetBufferMinimum(200); // try again hr = pClip.Create(m_pController, path); } if (hr >= 0) { pClip.SetStartPosition(m_tDuration); m_tDuration += pClip.Duration(); // if this is the first clip, create the render graph if (m_Clips.Count == 1) { m_pRenderGraph = new FilterGraph() as IGraphBuilder; hr = m_pController.CreateRenderGraph(pClip.SinkFilter(), m_pRenderGraph, out m_pRenderGraphSourceFilter); if (hr >= 0 && m_hwndApp != IntPtr.Zero) { IMediaEventEx pME = m_pRenderGraph as IMediaEventEx; if (pME != null) { pME.SetNotifyWindow(m_hwndApp, m_msgEvent, IntPtr.Zero); } } } } else { pClip.Dispose(); m_Clips.RemoveAt(it); } return hr; }
protected override void FreeResources() { /* We run the StopInternal() to avoid any * Dispatcher VeryifyAccess() issues */ StopInternal(); /* Let's clean up the base * class's stuff first */ base.FreeResources(); #if DEBUG if(m_rotEntry != null) m_rotEntry.Dispose(); m_rotEntry = null; #endif if(m_videoFrame != null) { m_videoFrame.Dispose(); m_videoFrame = null; } if (m_renderer != null) { Marshal.FinalReleaseComObject(m_renderer); m_renderer = null; } if (m_captureDevice != null) { Marshal.FinalReleaseComObject(m_captureDevice); m_captureDevice = null; } if (m_sampleGrabber != null) { Marshal.FinalReleaseComObject(m_sampleGrabber); m_sampleGrabber = null; } if (m_graph != null) { Marshal.FinalReleaseComObject(m_graph); m_graph = null; InvokeMediaClosed(new EventArgs()); } if (m_pBridge != null) { Marshal.ReleaseComObject(m_pBridge); m_pBridge = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } }
// Release all the members of the source graph private void ReleaseSelectMembers() { if (m_rot1 != null) { m_rot1.Dispose(); m_rot1 = null; } if (m_pBridge != null) { Marshal.ReleaseComObject(m_pBridge); m_pBridge = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } if (m_pSourceGraphSinkFilter != null) { Marshal.ReleaseComObject(m_pSourceGraphSinkFilter); m_pSourceGraphSinkFilter = null; } if (m_pCapOutput != null) { Marshal.ReleaseComObject(m_pCapOutput); m_pCapOutput = null; } if (m_pSourceGraph != null) { Marshal.ReleaseComObject(m_pSourceGraph); m_pSourceGraph = null; } }
/// <summary> /// Creates a test pattern /// </summary> /// <param name="controller">GMFBridgeController to use</param> /// <param name="compressVideo">true if the video should be compressed, or false for raw frames</param> public TestPattern(IGMFBridgeController controller, bool compressVideo) { this.Controller = controller; Construct(compressVideo); }