【问题标题】:Different approaches on getting captured video frames in DirectShow在 DirectShow 中获取捕获的视频帧的不同方法
【发布时间】:2012-05-24 18:26:27
【问题描述】:

我正在使用回调机制来抓取媒体应用程序中的网络摄像头帧。它可以工作,但由于在回调本身中执行了某些额外的缓冲区函数,所以速度很慢。

现在我正在尝试另一种获取帧的方法。也就是说,调用一个方法并抓取帧(而不是回调)。我在 CodeProject 中使用了一个使用 IVMRWindowlessControl9::GetCurrentImage 的示例。

我遇到了以下问题。

  1. 在 Microsoft 网络摄像头中,预览版在 Windows 7 上无法呈现(仅黑屏)。但同一个摄像头在 XP 上呈现了预览版。

我的疑问是,VMR 特定功能是否会依赖于不同平台上的相机驱动程序?不然怎么会有这种差别?

  1. 无论示例应用程序在哪里工作,我都观察到生成的 BITMAPINFOHEADER 结构的 biBitCount 成员是 32。

这是应用程序设置的值还是 VMR 操作的驱动程序设置?这是如何配置的? 最后,获取网络摄像头帧的最佳方法是什么?回调方法?还是直接方法?

提前致谢,

【问题讨论】:

    标签: directshow webcam samplegrabber


    【解决方案1】:

    IVMRWindowlessControl9::GetCurrentImage 用于偶尔的快照,而不是用于常规图像抓取。

    引用自 MSDN:

    这个方法可以随时调用,不管过滤器处于什么状态 是否处于运行、停止或暂停状态。 但是,经常调用 此方法会降低视频播放性能。

    此方法从一开始很慢的视频内存中读取。此方法会转换(即再次变慢)到 RGB 颜色空间,因为这种格式最适合非流式应用程序,并且兼容性问题较少。

    总而言之,您可以将其用于定期图像抓取,但这不是您应该做的。要以流传输速率捕获,您需要在管道中使用过滤器,或者使用带有回调的 Sample Grabber。

    【讨论】:

    • 谢谢罗曼。让我试试,如果有问题我会回来的。
    • 您好,运行图表后,我尝试了以下操作。 hr = g_pGrabber->GetCurrentBuffer(&cbBuffer, NULL);但在这里我得到 hr 为 -2147220953。我得到了相应的 COM 错误字符串作为 IDispatch 错误 #39。这是什么错误?
    • -2147220953 是 VFW_E_WRONG_STATE social.msdn.microsoft.com/Forums/en-US/…
    • 嗨 Roman,我做了 g_pGrabber->SetBufferSamples(TRUE);然后我调用了 RenderStream 两次 - 一次用于 Capture(使用 Sample grabber 和 Null 渲染器),然后用于预览。然后我运行图表。然后调用 GetCurrentBuffer 两次,首先是获取大小,然后是实际缓冲区。但我没有看到实际缓冲区发生任何变化。似乎只捕获了第一帧。我也没有设置One Shot。默认情况下,一枪被禁用,对吗?请澄清。
    • @mbaros:SetOneShot、BufferCB、GetCurrentBuffer、SetBufferSamples 是为了让您获得单帧。要获取所有帧,您需要执行类似的逻辑来设置图表。你不做 SetOneShot 和 SetBufferSamples。你同样运行并等待完成。你另外做的是ISampleGrabber::SetCallback 并提供你的回调接口。它将为处理的每一帧调用,尤其是。通过 SampleCB 调用。在通话中,您可以保存或处理各个帧。这样您就可以获得视频文件的所有帧。
    猜你喜欢
    • 2011-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多