我正在尝试使用C#中的DirectShowNet更改默认的网络摄像头分辨率,从我收集的内容我需要更改它来调用windows win32 api dll中的内置VideoInfoHeader类以进行avi捕获。我有来自DirectShowNet的以下代码:
hr = capGraph.SetFiltergraph( graphBuilder );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
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);
hr = graphBuilder.AddFilter( capFilter, "Ds.NET Video Capture Device" );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
DsUtils.ShowCapPinDialog( capGraph, capFilter, this.Handle );
Guid sub = MediaSubType.Avi;
hr = capGraph.SetOutputFileName( ref sub, fileName, out mux, out sink );
if( hr < 0 )
Marshal.ThrowExceptionForHR( hr );
Guid cat = PinCategory.Capture;
Guid med = MediaType.Video;
hr = capGraph.RenderStream( ref cat, ref med, capFilter, null, mux ); // stream to file
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;
事情是我无法访问videoInfoHeader,因为在这一行:hr = sampGrabber.GetConnectedMediaType(media); 它说并且hr小于0因此抛出此错误:接口有太多方法来触发事件(来自HRESULT的异常:0x80040209)
它不会读取VideoInfoHeader位,因此我无法更改网络摄像头捕获的分辨率,任何人都知道更好的方法来执行此操作或如何解决此问题?
答案 0 :(得分:3)
确保在查找HR错误代码时,使用DirectShow Error and Success Code list查找它们,而不是通用HR代码列表。您将从该列表中看到0x80040209的实际含义是:
VFW_E_NOT_CONNECTED由于未连接引脚,因此无法执行操作。
您的图表似乎未连接样本抓取器过滤器。确保在通话时将样本抓取器传递给RenderStream
。
答案 1 :(得分:0)
更改网络摄像头分辨率的正确方法是查询其输出引脚IAMStreamConfig界面。它可以列出可用的格式和分辨率,然后选择一个。如果您运行GraphEditPlus并右键单击相机滤镜的输出引脚,您将能够看到该列表并选择分辨率。然后你可以生成代码(通过文件菜单),看看它是如何在C#中完成的。