其中这个代码是报错的部分,我在第一次打开视频的时候,一点问题没有,但是当把窗体的子窗口关闭,再次打开的时候就会报出错误,hr就会变为负值,希望大家可以给出解决的办法吧,谢谢了 
这代码主要是实现显示摄像头的图像显示,自己琢磨了好久了也解决不了,希望大家帮忙吧 
                Guid cat = PinCategory.Preview; 
                //设置媒体类型为视频帧 
                Guid med = MediaType.Video; 
                //输出视频流 
                hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, null); 
完整的程序代码如下: 
        ///  
        /// 构建Capture Graph 
        /// 
        bool SetupGraph() 
        { 
            int hr; 
            try 
            { 
                //创建Capture Graph Builder组件graphBuilder,并初始化 
                hr = capGraph.SetFiltergraph(graphBuilder); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                //通过AddFilter将graphBuilder组件添加到视频捕获设备capFilter中 
                hr = graphBuilder.AddFilter(capFilter, "视频驱动"); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr);                 //DsUtils.ShowCapPinDialog( capGraph, capFilter, this.Handle ); 
                //设置媒体类型 
                AMMediaType media = new AMMediaType(); 
                media.majorType = MediaType.Video; 
                media.subType = MediaSubType.RGB24; 
                media.formatType = FormatType.VideoInfo; 
                hr = sampGrabber.SetMediaType(media); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                //将graphBuilder添加到baseGrabFlt中 
                hr = graphBuilder.AddFilter(baseGrabFlt, "Ds.NET Grabber"); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                //选择Preview 输出Pin 
                Guid cat = PinCategory.Preview; 
                //设置媒体类型为视频帧 
                Guid med = MediaType.Video; 
                //输出视频流 
                hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, null); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                //选择Capture输出Pin 
                cat = PinCategory.Capture; 
                //选择Capture输出Pin 
                med = MediaType.Video; 
                //输出视频流 
                hr = capGraph.RenderStream(ref cat, ref med, capFilter, null, baseGrabFlt); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                //以下代码实现视频帧捕捉功能 
                media = new AMMediaType(); 
                hr = sampGrabber.GetConnectedMediaType(media); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr); 
                if ((media.formatType != FormatType.VideoInfo) || (media.formatPtr == IntPtr.Zero)) 
                    throw new NotSupportedException("Unknown Grabber Media Format");                 videoInfoHeader = (VideoInfoHeader)Marshal.PtrToStructure(media.formatPtr, typeof(VideoInfoHeader)); 
                Marshal.FreeCoTaskMem(media.formatPtr); media.formatPtr = IntPtr.Zero;                 hr = sampGrabber.SetBufferSamples(false); 
                if (hr == 0) 
                    hr = sampGrabber.SetOneShot(false); 
                if (hr == 0) 
                    hr = sampGrabber.SetCallback(null, 0); 
                if (hr < 0) 
                    Marshal.ThrowExceptionForHR(hr);                 return true; 
            } 
            catch (Exception ee) 
            { 
                LOG.Error(ee.ToString()); 
                MessageBox.Show(this, "不能启动视频\r\n" + ee.Message, "系统提示:", MessageBoxButtons.OK, MessageBoxIcon.Stop); 
                CloseInterfaces(); 
                return false; 
            } 
        }
-----------------------------------------------
释放资源是以下代码,可能还是释放的时候某些资源没有释放掉,所以才会出现问题,望各位大哥给提出宝贵意见! 
        /// <summary> 
        /// 清理并释放DirectShow. 
        /// </summary>        
        void CloseInterfaces() 
        { 
            int hr = 0; 
            try 
            { 
                lock (this) 
                { 
                    if (mediaEvt != null) 
                    { 
                        hr = this.mediaEvt.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero); 
                        //DsError.ThrowExceptionForHR(hr); 
                    } 
                    // Release and zero DirectShow interfaces 
                    if (rotCookie != 0) 
                    { 
                        DsROT.RemoveGraphFromRot(ref rotCookie);                        
                    } 
                    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; 
                    } 
                    GC.Collect(); 
                } 
            } 
            catch (Exception) 
            { } 
        }

解决方案 »

  1.   

    你的这个 CloseInterfaces() 
    函数是不是没有调用,你可以在切换是或不使用摄像头时进行调用
      

  2.   

    C++ 最后要加上这个,在return 前,要不下次用不了.你应该没加,我也有遇到过.
      

  3.   

    什么叫做“资源没有释放掉”?这个成了万金油随便抹了。你确切知道需要“释放”什么东西的时候才去释放它,否则在根本没有必要花正规程序处理的时间和空间(而不是GC程序的时间和空间)去处理它,才是不应该的。
    .net摄像头的,你打开之前就要关闭一次,不管之前有没有关闭过。这是底层的要求。