其中这个代码是报错的部分,我在第一次打开视频的时候,一点问题没有,但是当把窗体的子窗口关闭,再次打开的时候就会报出错误,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)
{ }
}
这代码主要是实现显示摄像头的图像显示,自己琢磨了好久了也解决不了,希望大家帮忙吧
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)
{ }
}
函数是不是没有调用,你可以在切换是或不使用摄像头时进行调用
.net摄像头的,你打开之前就要关闭一次,不管之前有没有关闭过。这是底层的要求。