我想开发一个虚拟网络摄像头驱动程序,从用户模式我将图像传递给它,它将显示为网络摄像头输出。
我不想使用DirectX过滤器和CSourceStream等。因为它们不适用于某些不使用DirectX捕获网络摄像头图像的程序。
我必须写一个内核模式设备驱动程序。
有什么想法吗?我尝试了DDK样本中的testcap,但它没有处理来自用户模式的图像并且没有得到任何输入,只是它在网络摄像头中显示7种颜色......
非常感谢任何帮助。 感谢
谢谢大家!
我从这里尝试了代码: http://tmhare.mvps.org/downloads.htm(找到捕获源过滤器)
当我在雅虎,MSN编译它时效果很好,但它崩溃了AIM,Internet Explorer Flash网络摄像头,Firefox Flash网络摄像头和Skype ......在8次调用之后,我在QueryInterface中崩溃了,我发现它跟踪它有很多技巧..
现在我知道,它在第8次打电话时崩溃了 HRESULT CVCamStream :: QueryInterface(REFIID riid,void ** ppv)
如果,我的意思是,当它达到最后时第8次通话: 返回CSourceStream :: QueryInterface(riid,ppv);它位于Filters.cpp的第17行
为什么你认为我会崩溃?
感谢大家指导我找到正确的解决方案,即DirectShow,而不是驱动程序
答案 0 :(得分:16)
Microsoft提供了多种API,可以访问图像数据。
DirectShow具体:
要在Windows下创建图像采集设备,您必须提供实现流类接口(或更新的Avstream)的设备(驱动程序),或者必须编写必须添加到VideoInputCategory枚举器的用户模式COM对象。
Avstream示例为真实图像采集设备提供了一切。实际设备的下层确实只缺少。
如果您可以设计一个设备,您应该创建它兼容DCAM或UVC。两者都有windows提供的内置驱动程序。
如何编写软件源设备:
您必须创建一个DirectShow过滤器,该过滤器至少提供一个输出引脚并在VideoInputCategory下注册。某些应用程序可能需要一些来自捕获应用程序的接口,但这些接口取决于应用程序本身。试用过滤器的简单应用程序是Plattform 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。
答案 1 :(得分:4)
您无法决定其他程序如何调用您的驱动程序。大多数程序将使用DirectShow。有些人会使用win3.x技术VFW。许多新程序,包括Windows XP的扫描仪和相机向导,都可以通过WIA界面给您打电话。如果您不想实现所有这些,则需要通过WDM at least provide the DirectShow interface并让vfwwdm32.dll为您提供VFW接口,或编写您自己的VFW驱动程序。