20

我想开发一个虚拟网络摄像头驱动程序,我将从用户模式将图像传递给它,它将显示为网络摄像头输出。

我不想使用 DirectX 过滤器和 CSourceStream 等。因为它们不适用于某些不使用 DirectX 捕获网络摄像头图像的程序。

我必须编写一个内核模式设备驱动程序。

有任何想法吗?我从 DDK 样本中尝试了 testcap,但它不处理来自用户模式的图像,也没有得到任何输入,只是在网络摄像头中显示 7 种颜色......

任何帮助将不胜感激。谢谢


谢谢你们!

我从这里尝试了代码:http: //tmhare.mvps.org/downloads.htm (查找捕获源过滤器)

当我在 Yahoo、MSN 中编译它时它运行良好,但它使 AIM、Internet Explorer Flash 网络摄像头、Firefox Flash 网络摄像头和 Skype 崩溃......经过 8 次调用后,我在 QueryInterface 中崩溃了,我通过跟踪它找到了它很多套路。。

现在我知道,它在第 8 次调用 HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv) 时崩溃

如果达到最后一个,则进行第 8 次调用,我的意思是: return CSourceStream::QueryInterface(riid, ppv);

它在 Filters.cpp 的第 17 行

为什么你认为我会崩溃?

感谢大家指导我找到正确的解决方案,即 DirectShow,而不是驱动程序

4

2 回答 2

18

Microsoft 有几个 API 提供对图像数据的访问。

  • Twain:用于从扫描仪等中捕获单个图像。
  • WIA:这似乎已经退化为一个单一的图像编解码器库。
  • VfW:一个非常古老的(Win16)API,它只适用于视频文件编码/解码,但支持一些视频采集。
  • DirectShow:以前属于 DirectX SDK,目前属于 Platform SDK。这是寻找当前(通用)流媒体解决方案的地方。
  • Windows Media/Media Foundation:这似乎更适合视频播放/重新编码。
  • 制造商特定库:Pylon/Halcon/Imaging Control/...

DirectShow 具体:

要在 Windows 下创建图像采集设备,您必须提供一个设备(驱动程序)来实现流类接口(或更新的 Avstream),或者您必须编写一个必须添加到 VideoInputCategory 枚举器的用户模式 ​​COM 对象。

Avstream 示例为真实的图像采集设备提供了一切。只有实际设备的底层确实丢失了。

如果您可以设计设备,则应创建与 DCAM 或 UVC 兼容的设备。两者都有 Windows 提供的内置驱动程序。


如何编写软件源设备:

您必须创建一个 DirectShow 过滤器,它至少提供一个输出引脚并将其注册到 VideoInputCategory 下。某些应用程序可能需要来自捕获应用程序的多个接口,但这些接口取决于应用程序本身。用于试用过滤器的简单应用程序是 Platform SDK 中提供的 GraphEdit 和 AMCap。

一些代码:

#include <InitGuid.h>
#include <streams.h>


const AMOVIESETUP_MEDIATYPE s_VideoPinType =
{
    &MEDIATYPE_Video,   // Major type
    &MEDIATYPE_NULL     // Minor type
};

const AMOVIESETUP_PIN s_VideoOutputPin =
{
    L"Output",              // Pin string name
    FALSE,                  // Is it rendered
    TRUE,                   // Is it an output
    FALSE,                  // Can we have none
    FALSE,                  // Can we have many
    &CLSID_NULL,            // Connects to filter
    NULL,                   // Connects to pin
    1,                      // Number of types
    &s_VideoPinType         // Pin details
};

const AMOVIESETUP_FILTER s_Filter =
{
    &CLSID_MyFilter,        // Filter CLSID
    L"bla",         // String name
    MERIT_DO_NOT_USE,               // Filter merit
    1,                              // Number pins
    &s_VideoOutputPin               // Pin details
};

    REGFILTER2 rf2;
    rf2.dwVersion = 1;
    rf2.dwMerit = MERIT_DO_NOT_USE;
    rf2.cPins = 1;
    rf2.rgPins = s_Filter.lpPin;

    HRESULT hr = pFilterMapper->RegisterFilter( CLSID_MyFilter, _FriendlyName.c_str(), 0, 
        &CLSID_VideoInputDeviceCategory, _InstanceID.c_str(), &rf2 );
    if( FAILED( hr ) )
    {
        return false;
    }

    std::wstring inputCat = GUIDToWString( CLSID_VideoInputDeviceCategory );
    std::wstring regPath = L"CLSID\\" + inputCat + L"\\Instance";
    win32_utils::CRegKey hKeyInstancesDir;
    LONG rval = openKey( HKEY_CLASSES_ROOT, regPath, KEY_WRITE, hKeyInstancesDir );
    if( rval == ERROR_SUCCESS )
    {
        win32_utils::CRegKey hKeyInstance;
        rval = createKey( hKeyInstancesDir, _InstanceID, KEY_WRITE, hKeyInstance );

        ....

_InstanceID 是为此“虚拟设备”条目创建的 GUID。

于 2009-10-26T22:30:48.530 回答
4

您无法决定其他程序如何调用您的驱动程序。大多数程序将使用 DirectShow。有些会使用win3.x技术的VFW。许多新程序,包括 Windows XP 的扫描仪和相机向导,可能会通过 WIA 界面调用您。如果你不想实现这一切,你至少需要通过 WDM 提供 DirectShow 接口,让 vfwwdm32.dll 给你一个 VFW 接口,或者编写你自己的 VFW 驱动程序。

于 2009-10-26T21:56:30.843 回答