Beispiel #1
0
        /// <summary> start all the interfaces, graphs and preview window. </summary>
        bool StartupVideo(UCOMIMoniker mon)

        {
            int hr;

            try
            {
                if (!CreateCaptureDevice(mon))
                {
                    return(false);
                }

                if (!GetInterfaces())
                {
                    return(false);
                }

                if (!SetupGraph())
                {
                    return(false);
                }

                if (!SetupVideoWindow())
                {
                    return(false);
                }

                 #if DEBUG
                DsROT.AddGraphToRot(graphBuilder, out rotCookie);               // graphBuilder capGraph
                   #endif

                hr = mediaCtrl.Run();
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                bool hasTuner = DsUtils.ShowTunerPinDialog(capGraph, capFilter, this.Handle);
                // toolBarBtnTune.Enabled = hasTuner;

                return(true);
            }
            catch (Exception ee)
            {
                MessageBox.Show(this, "Could not start video stream\r\n" + ee.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return(false);
            }
        }
Beispiel #2
0
        /// <summary> start all the interfaces, graphs and preview window. </summary>
        bool StartupVideo(UCOMIMoniker mon)
        {
            int hr;

            try
            {
                if (!CreateCaptureDevice(mon))
                {
                    return(false);
                }

                if (!GetInterfaces())
                {
                    return(false);
                }

                if (!SetupGraph())
                {
                    return(false);
                }

                if (!SetupVideoWindow())
                {
                    return(false);
                }

#if DEBUG
                DsROT.AddGraphToRot(graphBuilder, out rotCookie);       // graphBuilder capGraph
#endif

                hr = mediaCtrl.Run();
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                CaptureImage(); // Begins updating...

                return(true);
            }
            catch (Exception ee)
            {
                MessageBox.Show(this, "Could not start video stream\r\n" + ee.Message, "DirectShow.NET", MessageBoxButtons.OK, MessageBoxIcon.Stop);
                return(false);
            }
        }
Beispiel #3
0
 protected void destroyGraph()
 {
     try
     {
         this.derenderGraph();
     }
     catch
     {
     }
     this.graphState        = GraphState.Null;
     this.isCaptureRendered = false;
     this.isPreviewRendered = false;
     if (this.rotCookie != 0)
     {
         DsROT.RemoveGraphFromRot(ref this.rotCookie);
         this.rotCookie = 0;
     }
     if (this.muxFilter != null)
     {
         this.graphBuilder.RemoveFilter(this.muxFilter);
     }
     if (this.baseGrabFlt != null)
     {
         this.graphBuilder.RemoveFilter(this.baseGrabFlt);
     }
     if (this.graphBuilder != null)
     {
         Marshal.ReleaseComObject(this.graphBuilder);
     }
     this.graphBuilder = null;
     if (this.muxFilter != null)
     {
         Marshal.ReleaseComObject(this.muxFilter);
     }
     this.muxFilter = null;
     if (this.baseGrabFlt != null)
     {
         Marshal.ReleaseComObject(this.baseGrabFlt);
     }
     this.baseGrabFlt  = null;
     this.mediaControl = null;
     this.videoWindow  = null;
     GC.Collect();
 }
Beispiel #4
0
        /// <summary> start all the interfaces, graphs and preview window. </summary>
        bool StartupVideo()
        {
            int hr;

            try
            {
                GetInterfaces();

                SetupGraph();

#if DEBUG
                DsROT.AddGraphToRot(graphBuilder, out rotCookie);               // graphBuilder capGraph
#endif

                return(true);
            }
            catch (Exception ee)
            {
                LogInfo(LogGroups.Console, "Could not start video stream\r\n" + ee.Message);
                return(false);
            }
        }
Beispiel #5
0
        /// <summary> do cleanup and release DirectShow. </summary>
        void CloseInterfaces()
        {
            int hr;

            try
            {
#if DEBUG
                if (rotCookie != 0)
                {
                    DsROT.RemoveGraphFromRot(ref rotCookie);
                }
#endif

                if (mediaCtrl != null)
                {
                    hr        = mediaCtrl.Stop();
                    mediaCtrl = null;
                }

                if (mediaEvt != null)
                {
                    hr       = mediaEvt.SetNotifyWindow(IntPtr.Zero, WM_GRAPHNOTIFY, IntPtr.Zero);
                    mediaEvt = null;
                }

                if (videoWin != null)
                {
                    hr       = videoWin.put_Visible(DsHlp.OAFALSE);
                    hr       = videoWin.put_Owner(IntPtr.Zero);
                    videoWin = null;
                }

                baseGrabFlt = null;
                if (sampGrabber != null)
                {
                    Marshal.ReleaseComObject(sampGrabber);
                }
                sampGrabber = null;

                if (capGraph != null)
                {
                    Marshal.ReleaseComObject(capGraph);
                }
                capGraph = null;

                if (graphBuilder != null)
                {
                    Marshal.ReleaseComObject(graphBuilder);
                }
                graphBuilder = null;

                if (capFilter != null)
                {
                    Marshal.ReleaseComObject(capFilter);
                }
                capFilter = null;

                if (capDevices != null)
                {
                    foreach (DsDevice d in capDevices)
                    {
                        d.Dispose();
                    }
                    capDevices = null;
                }
            }
            catch (Exception)
            { }
        }
Beispiel #6
0
        protected void createGraph()
        {
            Guid cat;
            Guid med;
            int  hr;

            // Ensure required properties are set
            if (videoDevice == null && audioDevice == null)
            {
                throw new ArgumentException("The video and/or audio device have not been set. Please set one or both to valid capture devices.\n");
            }

            // Skip if we are already created
            if ((int)graphState < (int)GraphState.Created)
            {
                // Garbage collect, ensure that previous filters are released
                GC.Collect();

                // Make a new filter graph
                graphBuilder = (IGraphBuilder)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.FilterGraph, true));

                // Get the Capture Graph Builder
                Guid clsid = Clsid.CaptureGraphBuilder2;
                Guid riid  = typeof(ICaptureGraphBuilder2).GUID;
                captureGraphBuilder = (ICaptureGraphBuilder2)BugFixes.InstantiateDirectShow(ref clsid, ref riid);

                // Link the CaptureGraphBuilder to the filter graph
                hr = captureGraphBuilder.SetFiltergraph(graphBuilder);
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }

                // Add the graph to the Running Object Table so it can be
                // viewed with GraphEdit
#if DEBUG
                rotCookie = DsROT.AddGraphToRot(graphBuilder);
#endif

                // Get the video device and add it to the filter graph
                if (VideoDevice != null)
                {
                    videoDeviceFilter = (IBaseFilter)Marshal.BindToMoniker(VideoDevice.MonikerString);
                    hr = graphBuilder.AddFilter(videoDeviceFilter, "Video Capture Device");
                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }
                }

                // Get the audio device and add it to the filter graph
                if (AudioDevice != null)
                {
                    audioDeviceFilter = (IBaseFilter)Marshal.BindToMoniker(AudioDevice.MonikerString);
                    hr = graphBuilder.AddFilter(audioDeviceFilter, "Audio Capture Device");
                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }
                }

                // Get the video compressor and add it to the filter graph
                if (VideoCompressor != null)
                {
                    videoCompressorFilter = (IBaseFilter)Marshal.BindToMoniker(VideoCompressor.MonikerString);
                    hr = graphBuilder.AddFilter(videoCompressorFilter, "Video Compressor");
                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }
                }

                // Get the audio compressor and add it to the filter graph
                if (AudioCompressor != null)
                {
                    audioCompressorFilter = (IBaseFilter)Marshal.BindToMoniker(AudioCompressor.MonikerString);
                    hr = graphBuilder.AddFilter(audioCompressorFilter, "Audio Compressor");
                    if (hr < 0)
                    {
                        Marshal.ThrowExceptionForHR(hr);
                    }
                }

                // Retrieve the stream control interface for the video device
                // FindInterface will also add any required filters
                // (WDM devices in particular may need additional
                // upstream filters to function).

                // Try looking for an interleaved media type
                object o;
                cat = PinCategory.Capture;
                med = MediaType.Interleaved;
                Guid iid = typeof(IAMStreamConfig).GUID;
                hr = captureGraphBuilder.FindInterface(
                    ref cat, ref med, videoDeviceFilter, ref iid, out o);

                if (hr != 0)
                {
                    // If not found, try looking for a video media type
                    med = MediaType.Video;
                    hr  = captureGraphBuilder.FindInterface(
                        ref cat, ref med, videoDeviceFilter, ref iid, out o);

                    if (hr != 0)
                    {
                        o = null;
                    }
                }
                videoStreamConfig = o as IAMStreamConfig;

                // Retrieve the stream control interface for the audio device
                o   = null;
                cat = PinCategory.Capture;
                med = MediaType.Audio;
                iid = typeof(IAMStreamConfig).GUID;
                hr  = captureGraphBuilder.FindInterface(
                    ref cat, ref med, audioDeviceFilter, ref iid, out o);
                if (hr != 0)
                {
                    o = null;
                }
                audioStreamConfig = o as IAMStreamConfig;

                // Retreive the media control interface (for starting/stopping graph)
                mediaControl = (IMediaControl)graphBuilder;

                // Reload any video crossbars
                if (videoSources != null)
                {
                    videoSources.Dispose();
                }
                videoSources = null;

                // Reload any audio crossbars
                if (audioSources != null)
                {
                    audioSources.Dispose();
                }
                audioSources = null;

                // Reload any property pages exposed by filters
                if (propertyPages != null)
                {
                    propertyPages.Dispose();
                }
                propertyPages = null;

                // Reload capabilities of video device
                videoCaps = null;

                // Reload capabilities of video device
                audioCaps = null;

                // Retrieve TV Tuner if available
                o   = null;
                cat = PinCategory.Capture;
                med = MediaType.Interleaved;
                iid = typeof(IAMTVTuner).GUID;
                hr  = captureGraphBuilder.FindInterface(
                    ref cat, ref med, videoDeviceFilter, ref iid, out o);
                if (hr != 0)
                {
                    med = MediaType.Video;
                    hr  = captureGraphBuilder.FindInterface(
                        ref cat, ref med, videoDeviceFilter, ref iid, out o);
                    if (hr != 0)
                    {
                        o = null;
                    }
                }
                IAMTVTuner t = o as IAMTVTuner;
                if (t != null)
                {
                    tuner = new Tuner(t);
                }



                // Update the state now that we are done
                graphState = GraphState.Created;
            }
        }
Beispiel #7
0
        protected void destroyGraph()
        {
            // Derender the graph (This will stop the graph
            // and release preview window. It also destroys
            // half of the graph which is unnecessary but
            // harmless here.) (ignore errors)
            try
            {
                derenderGraph();
            }
            catch
            {
            }

            // Update the state after derender because it
            // depends on correct status. But we also want to
            // update the state as early as possible in case
            // of error.
            graphState        = GraphState.Null;
            isCaptureRendered = false;
            isPreviewRendered = false;

            // Remove graph from the ROT
            if (rotCookie != 0)
            {
                DsROT.RemoveGraphFromRot(ref rotCookie);
                rotCookie = 0;
            }

            // Remove filters from the graph
            // This should be unnecessary but the Nvidia WDM
            // video driver cannot be used by this application
            // again unless we remove it. Ideally, we should
            // simply enumerate all the filters in the graph
            // and remove them. (ignore errors)
            if (muxFilter != null)
            {
                graphBuilder.RemoveFilter(muxFilter);
            }
            if (videoCompressorFilter != null)
            {
                graphBuilder.RemoveFilter(videoCompressorFilter);
            }
            if (audioCompressorFilter != null)
            {
                graphBuilder.RemoveFilter(audioCompressorFilter);
            }
            if (videoDeviceFilter != null)
            {
                graphBuilder.RemoveFilter(videoDeviceFilter);
            }
            if (audioDeviceFilter != null)
            {
                graphBuilder.RemoveFilter(audioDeviceFilter);
            }

            // Clean up properties
            if (videoSources != null)
            {
                videoSources.Dispose();
            }
            videoSources = null;
            if (audioSources != null)
            {
                audioSources.Dispose();
            }
            audioSources = null;
            if (propertyPages != null)
            {
                propertyPages.Dispose();
            }
            propertyPages = null;
            if (tuner != null)
            {
                tuner.Dispose();
            }
            tuner = null;

            // Cleanup
            if (graphBuilder != null)
            {
                Marshal.ReleaseComObject(graphBuilder);
            }
            graphBuilder = null;
            if (captureGraphBuilder != null)
            {
                Marshal.ReleaseComObject(captureGraphBuilder);
            }
            captureGraphBuilder = null;
            if (muxFilter != null)
            {
                Marshal.ReleaseComObject(muxFilter);
            }
            muxFilter = null;
            if (fileWriterFilter != null)
            {
                Marshal.ReleaseComObject(fileWriterFilter);
            }
            fileWriterFilter = null;
            if (videoDeviceFilter != null)
            {
                Marshal.ReleaseComObject(videoDeviceFilter);
            }
            videoDeviceFilter = null;
            if (audioDeviceFilter != null)
            {
                Marshal.ReleaseComObject(audioDeviceFilter);
            }
            audioDeviceFilter = null;
            if (videoCompressorFilter != null)
            {
                Marshal.ReleaseComObject(videoCompressorFilter);
            }
            videoCompressorFilter = null;
            if (audioCompressorFilter != null)
            {
                Marshal.ReleaseComObject(audioCompressorFilter);
            }
            audioCompressorFilter = null;

            // These are copies of graphBuilder
            mediaControl = null;
            videoWindow  = null;

            // For unmanaged objects we haven't released explicitly
            GC.Collect();
        }
Beispiel #8
0
        protected void CreateGraph()
        {
            // Ensure required properties are set
            if (videoDevice == null && audioDevice == null)
            {
                throw new ArgumentException("The video and/or audio device have not been set. Please set one or both to valid capture devices.\n");
            }

            // Skip if we are already created
            if ((int)graphState >= (int)GraphState.Created)
            {
                return;
            }

            // Make a new filter graph
            graphBuilder = (IGraphBuilder)Activator.CreateInstance(Type.GetTypeFromCLSID(Clsid.FilterGraph, true));

            // Get the Capture Graph Builder
            Guid clsid = Clsid.CaptureGraphBuilder2;
            Guid riid  = typeof(ICaptureGraphBuilder2).GUID;

            captureGraphBuilder = (ICaptureGraphBuilder2)DsBugWO.CreateDsInstance(ref clsid, ref riid);

            // Link the CaptureGraphBuilder to the filter graph
            var hr = captureGraphBuilder.SetFiltergraph(graphBuilder);

            if (hr < 0)
            {
                Marshal.ThrowExceptionForHR(hr);
            }

            // Add the graph to the Running Object Table so it can be
            // viewed with GraphEdit
#if DEBUG
            DsROT.AddGraphToRot(graphBuilder, out rotCookie);
#endif
            // Get the video device and add it to the filter graph
            if (VideoDevice != null)
            {
                videoDeviceFilter = (IBaseFilter)Marshal.BindToMoniker(VideoDevice.MonikerString);
                hr = graphBuilder.AddFilter(videoDeviceFilter, "Video Capture Device");
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            // Get the audio device and add it to the filter graph
            if (AudioDevice != null)
            {
                audioDeviceFilter = (IBaseFilter)Marshal.BindToMoniker(AudioDevice.MonikerString);
                hr = graphBuilder.AddFilter(audioDeviceFilter, "Audio Capture Device");
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            // Get the video compressor and add it to the filter graph
            if (VideoCompressor != null)
            {
                videoCompressorFilter = (IBaseFilter)Marshal.BindToMoniker(VideoCompressor.MonikerString);
                hr = graphBuilder.AddFilter(videoCompressorFilter, "Video Compressor");
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            // Get the audio compressor and add it to the filter graph
            if (AudioCompressor != null)
            {
                audioCompressorFilter = (IBaseFilter)Marshal.BindToMoniker(AudioCompressor.MonikerString);
                hr = graphBuilder.AddFilter(audioCompressorFilter, "Audio Compressor");
                if (hr < 0)
                {
                    Marshal.ThrowExceptionForHR(hr);
                }
            }

            // Retrieve the stream control interface for the video device
            // FindInterface will also add any required filters
            // (WDM devices in particular may need additional
            // upstream filters to function).

            // Try looking for an interleaved media type
            object o;
            var    cat = PinCategory.Capture;
            var    med = MediaType.Interleaved;
            Guid   iid = typeof(IAMStreamConfig).GUID;
            hr = captureGraphBuilder.FindInterface(
                ref cat, ref med, videoDeviceFilter, ref iid, out o);
            if (hr != 0)
            {
                // If not found, try looking for a video media type
                med = MediaType.Video;
                hr  = captureGraphBuilder.FindInterface(
                    ref cat, ref med, videoDeviceFilter, ref iid, out o);
                if (hr != 0)
                {
                    o = null;
                }
            }
            videoStreamConfig = o as IAMStreamConfig;

            cat = PinCategory.Preview;
            med = MediaType.Interleaved;
            iid = typeof(IAMStreamConfig).GUID;
            hr  = captureGraphBuilder.FindInterface(
                ref cat, ref med, videoDeviceFilter, ref iid, out o);

            if (hr != 0)
            {
                // If not found, try looking for a video media type
                med = MediaType.Video;
                hr  = captureGraphBuilder.FindInterface(
                    ref cat, ref med, videoDeviceFilter, ref iid, out o);
                if (hr != 0)
                {
                    o = null;
                }
            }
            previewStreamConfig = o as IAMStreamConfig;
            cat = PinCategory.Capture;
            med = MediaType.Audio;
            iid = typeof(IAMStreamConfig).GUID;
            if ((_audioViaPci) &&
                (audioDeviceFilter == null) && (videoDeviceFilter != null))
            {
                hr = captureGraphBuilder.FindInterface(ref cat, ref med, videoDeviceFilter, ref iid, out o);
            }
            else
            {
                hr = captureGraphBuilder.FindInterface(ref cat, ref med, audioDeviceFilter, ref iid, out o);
            }

            if (hr != 0)
            {
                o = null;
            }
            audioStreamConfig = o as IAMStreamConfig;

            // Retreive the media control interface (for starting/stopping graph)
            mediaControl = graphBuilder as IMediaControl;

            // Reload any video crossbars
            videoSources?.Dispose();
            videoSources = null;

            // Reload any audio crossbars
            audioSources?.Dispose();
            audioSources = null;

            // Reload any property pages exposed by filters
            //PropertyPages = null;

            // Reload capabilities of video device
            videoCaps   = null;
            previewCaps = null;

            // Reload capabilities of video device
            audioCaps = null;


            graphState = GraphState.Created;
        }
Beispiel #9
0
 protected void destroyGraph()
 {
     try
     {
         this.derenderGraph();
     }
     catch
     {
     }
     this.graphState        = GraphState.Null;
     this.isCaptureRendered = false;
     this.isPreviewRendered = false;
     if (this.rotCookie != 0)
     {
         DsROT.RemoveGraphFromRot(ref this.rotCookie);
         this.rotCookie = 0;
     }
     if (this.muxFilter != null)
     {
         this.graphBuilder.RemoveFilter(this.muxFilter);
     }
     if (this.baseGrabFlt != null)
     {
         this.graphBuilder.RemoveFilter(this.baseGrabFlt);
     }
     if (this.videoCompressorFilter != null)
     {
         this.graphBuilder.RemoveFilter(this.videoCompressorFilter);
     }
     if (this.audioCompressorFilter != null)
     {
         this.graphBuilder.RemoveFilter(this.audioCompressorFilter);
     }
     if (this.videoDeviceFilter != null)
     {
         this.graphBuilder.RemoveFilter(this.videoDeviceFilter);
     }
     if (this.audioDeviceFilter != null)
     {
         this.graphBuilder.RemoveFilter(this.audioDeviceFilter);
     }
     if (this.videoSources != null)
     {
         this.videoSources.Dispose();
     }
     this.videoSources = null;
     if (this.audioSources != null)
     {
         this.audioSources.Dispose();
     }
     this.audioSources = null;
     if (this.propertyPages != null)
     {
         this.propertyPages.Dispose();
     }
     this.propertyPages = null;
     if (this.tuner != null)
     {
         this.tuner.Dispose();
     }
     this.tuner = null;
     if (this.graphBuilder != null)
     {
         Marshal.ReleaseComObject(this.graphBuilder);
     }
     this.graphBuilder = null;
     if (this.captureGraphBuilder != null)
     {
         Marshal.ReleaseComObject(this.captureGraphBuilder);
     }
     this.captureGraphBuilder = null;
     if (this.muxFilter != null)
     {
         Marshal.ReleaseComObject(this.muxFilter);
     }
     this.muxFilter = null;
     if (this.baseGrabFlt != null)
     {
         Marshal.ReleaseComObject(this.baseGrabFlt);
     }
     this.baseGrabFlt = null;
     if (this.fileWriterFilter != null)
     {
         Marshal.ReleaseComObject(this.fileWriterFilter);
     }
     this.fileWriterFilter = null;
     if (this.videoDeviceFilter != null)
     {
         Marshal.ReleaseComObject(this.videoDeviceFilter);
     }
     this.videoDeviceFilter = null;
     if (this.audioDeviceFilter != null)
     {
         Marshal.ReleaseComObject(this.audioDeviceFilter);
     }
     this.audioDeviceFilter = null;
     if (this.videoCompressorFilter != null)
     {
         Marshal.ReleaseComObject(this.videoCompressorFilter);
     }
     this.videoCompressorFilter = null;
     if (this.audioCompressorFilter != null)
     {
         Marshal.ReleaseComObject(this.audioCompressorFilter);
     }
     this.audioCompressorFilter = null;
     this.mediaControl          = null;
     this.videoWindow           = null;
     GC.Collect();
 }
Beispiel #10
0
        /// <summary> do cleanup and release DirectShow. </summary>
        void CloseInterfaces()
        {
            int hr;

#if DEBUG
            if (rotCookie != 0)
            {
                DsROT.RemoveGraphFromRot(ref rotCookie);
            }
#endif

            if (mediaCtrl != null)
            {
                hr = mediaCtrl.Stop();
                Marshal.ReleaseComObject(mediaCtrl);
                mediaCtrl = null;
            }

            if (mediaEvt != null)
            {
                Marshal.ReleaseComObject(mediaEvt);
                mediaEvt = null;
            }

            if (baseGrabFlt != null)
            {
                Marshal.ReleaseComObject(baseGrabFlt);
                baseGrabFlt = null;
            }

            if (sampleGrabber != null)
            {
                Marshal.ReleaseComObject(sampleGrabber);
                sampleGrabber = null;
            }

            if (grabberConfig != null)
            {
                Marshal.ReleaseComObject(grabberConfig);
                grabberConfig = null;
            }

            if (capGraph != null)
            {
                Marshal.ReleaseComObject(capGraph);
                capGraph = null;
            }

            if (graphBuilder != null)
            {
                Marshal.ReleaseComObject(graphBuilder);
                graphBuilder = null;
            }

            if (dev != null)
            {
                dev.Dispose();
                dev = null;
            }

            if (wmVideoDecoder != null)
            {
                Marshal.ReleaseComObject(wmVideoDecoder);
                wmVideoDecoder = null;
            }

            if (capFilter != null)
            {
                Marshal.ReleaseComObject(capFilter);
                capFilter = null;
            }

            if (capDevices != null)
            {
                foreach (DsDevice d in capDevices)
                {
                    d.Dispose();
                }
                capDevices = null;
            }

            if (atiCrossbar != null)
            {
                Marshal.ReleaseComObject(atiCrossbar);
                atiCrossbar = null;
            }

            if (motionVector != null)
            {
                Marshal.ReleaseComObject(motionVector);
                motionVector = null;
            }

            if (teeSplitter != null)
            {
                Marshal.ReleaseComObject(teeSplitter);
                teeSplitter = null;
            }

            if (videoRenderer != null)
            {
                Marshal.ReleaseComObject(videoRenderer);
                videoRenderer = null;
            }

            if (vectorGrabber != null)
            {
                //vectorGrabber.SetCallback(null); // FIXME: sometimes, this causes an exception
                Marshal.ReleaseComObject(vectorGrabber);
                vectorGrabber = null;
            }

            if (crossBar != null)
            {
                Marshal.ReleaseComObject(crossBar);
                crossBar = null;
            }
        }