gpt4 book ai didi

c# - 使用 DirectShow 预览时无法捕获相机源

转载 作者:太空宇宙 更新时间:2023-11-03 12:42:02 48 4
gpt4 key购买 nike

该应用程序是使用 DirectShowLib 和 USB 摄像头 (Logitech C930e) 在 C# 中实现的。该图是使用 RenderStream 方法编译的。 SmartTee 过滤器是自动生成的,因为没有提供预览引脚。

RenderStream 被调用一次用于预览,然后用于捕获。但是,即使交换(捕获然后预览),它也无法将第二次调用连接到 SmartTee。抛出的错误处理程序是:-2147024809 (0x80070057; E_INVALIDARG; 参数不正确)

代码片段如下

    DirectShowLib.ISampleGrabber sg = null;
DirectShowLib.ICaptureGraphBuilder2 cg = null;
DirectShowLib.IGraphBuilder fg = null;

IBaseFilter capFilter;
IBaseFilter videoCompressorFilter;
IBaseFilter muxFilter;
IBaseFilter grabFilter;
IBaseFilter VideoRendererFilter;

Guid captureCat = PinCategory.Capture;
Guid previewCat = PinCategory.Preview;
Guid med = MediaType.Video;

DsGuid DSCaptureCat = (DsGuid)captureCat;
DsGuid DSPreviewCat = (DsGuid)previewCat;
DsGuid DSmed = (DsGuid)med;

/*GetInterfaces*/
Type comType = null;
object comObj = null;
fg = (IGraphBuilder)new FilterGraph();
comType = Type.GetTypeFromCLSID(CgGuid);
comObj = Activator.CreateInstance(comType);
cg = (ICaptureGraphBuilder2)comObj; comObj = null;
sg = (ISampleGrabber)new SampleGrabber();
grabFilter = (IBaseFilter)sg;
VideoRendererFilter = (IBaseFilter)new VideoRenderer();

/*CreateCaptureDevice*/
object capObj = null;
capFilter = (IBaseFilter)capObj;

/*SetupGraph*/
hr = cg.SetFiltergraph(fg);

if (renderFromDevice && deviceSet)
{
hr = fg.AddFilter(capFilter, "CapFilter");
}

AMMediaType media = new AMMediaType();
media.majorType = MediaType.Video;
media.subType = MediaSubType.RGB24;
media.formatType = FormatType.VideoInfo;
hr = sg.SetMediaType(media);

DsUtils.FreeAMMediaType(media);
media = null;


[1]
/*RenderToScreen*/
hr = fg.AddFilter(grabFilter, "FrameGrabFilter");

hr = cg.RenderStream(DSPreviewCat, DSmed, capFilter, grabFilter, null);

[2]
/*DerenderGraph*/
if (renderFromDevice)
removeDownstream(capFilter, videoCompressorFilter == null);
else if (grabFilter != null)
removeDownstream(grabFilter, true);

[3]
/*RenderToMovie*/
videoFilename = Path.Combine(dirname, "interview.avi");

cg.SetOutputFileName(MediaSubType.Avi, videoFilename, out muxFilter, out fileWriterFilter); //this automatically adds muxFilter to graph!

string s;
AMMediaType media = new AMMediaType();
hr = fileWriterFilter.GetCurFile(out s, media);
hr = fileWriterFilter.SetFileName(videoFilename, media);
DsUtils.FreeAMMediaType(media);
media = null;

hr = fg.AddFilter(muxFilter, "MuxFilter"); //this adds the second muxFilter! now removed

hr = cg.RenderStream(DSCaptureCat, DSmed, capFilter, null, muxFilter);

[4]
/*RenderToScreen2*/
hr = fg.AddFilter(grabFilter, "FrameGrabFilter");

hr = fg.AddFilter(VideoRendererFilter, "VideoRendererFilter");

IEnumFilters enumFilters = null;
FilterInfo pInfo;
IBaseFilter pFilter1, pFilter2, pFilter3;
IPin outPin1, inPin1, outPin2, inPin2, inPin3;

hr = fg.EnumFilters(out enumFilters);

IBaseFilter[] filters = new IBaseFilter[1];
int fetched;

while (enumFilters.Next(1, filters, out fetched) == 0)
{
hr = filters[0].QueryFilterInfo(out pInfo);

hr = fg.FindFilterByName("Smart Tee", out pFilter1);

inPin1 = DsFindPin.ByDirection(pFilter1, PinDirection.Input, 0);
outPin1 = DsFindPin.ByName(pFilter1, "Preview");

hr = fg.FindFilterByName("FrameGrabFilter", out pFilter2);

inPin2 = DsFindPin.ByDirection(pFilter2, PinDirection.Input, 0);
outPin2 = DsFindPin.ByDirection(pFilter2, PinDirection.Output, 0);

hr = fg.FindFilterByName("VideoRendererFilter", out pFilter3);

inPin3 = DsFindPin.ByDirection(pFilter3, PinDirection.Input, 0);

hr = fg.Connect(outPin1, inPin2);

hr = fg.Connect(outPin2, inPin3);
}

下面的 GraphEdit 显示了到图形的远程连接。通过手动将 SmartTee 捕获链接到 GraphEdit 中的 MuxFilter,该图运行良好。

任何关于可能的错误原因的提示将不胜感激。

最佳答案

没有看到对 ICaptureGRaphBuilder2.RenderStream 的实际调用,我只能对 E_INVALIDARG 错误做出一些假设。但是,从与图形的远程连接来看,我可以看出您的图形存在严重错误。两个输出引脚不应连接到同一个输入引脚。您应该始终首先为捕获路径调用 RenderStream,因为它是协商媒体类型的捕获引脚。您的源过滤器上已经有 Capture pin(为什么其中有 2 个?)。我认为您需要像这样调用您的 Capture RenderStream:

RenderStream(PIN_CATEGORY_CAPTURE, MEDIATYPE_Video, pSource, pMux, pWriter);

地点:pSource是Video Camera Terminal CapFilter的IBaseFilter接口(interface),pMux 是 MuxFilter 的 IBaseFilter 接口(interface)(应该只有一个 MuxFilter 添加到图中!),pWriter 是 Writer 过滤器 (interview.avi) 的 IBaseFilter 接口(interface)。

您应该只添加一个 Video Camera Terminal CapFilter 实例、一个 MuxFilter (AVI Mux) 实例和一个 File Writer 过滤器实例 (interview.avi)。使用此设置,捕获路径的 RenderStream 调用应该会成功。之后,您可以尝试为预览路径调用 RenderStream,如果智能 T 恤尚未在第一次调用时添加,则应添加。如果我可以进一步帮助您,请告诉我。

关于c# - 使用 DirectShow 预览时无法捕获相机源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38597260/

48 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com