C++ 虚拟网络摄像头驱动程序
我想开发一个虚拟网络摄像头驱动程序,从用户模式,我会传递图像到它,它将显示为网络摄像头输出 我不想使用DirectX过滤器和CSourceStream等,因为它们不适用于某些不使用DirectX捕获网络摄像头图像的程序 我必须写一个内核模式的设备驱动程序 有什么想法吗?我尝试了DDK样本中的testcap,但它不处理用户模式下的图像,也不获取任何输入,只在网络摄像头中显示7种颜色 任何帮助都将不胜感激。 谢谢C++ 虚拟网络摄像头驱动程序,c++,webcam,directshow,device-driver,wdk,C++,Webcam,Directshow,Device Driver,Wdk,我想开发一个虚拟网络摄像头驱动程序,从用户模式,我会传递图像到它,它将显示为网络摄像头输出 我不想使用DirectX过滤器和CSourceStream等,因为它们不适用于某些不使用DirectX捕获网络摄像头图像的程序 我必须写一个内核模式的设备驱动程序 有什么想法吗?我尝试了DDK样本中的testcap,但它不处理用户模式下的图像,也不获取任何输入,只在网络摄像头中显示7种颜色 任何帮助都将不胜感激。 谢谢 谢谢大家! 我在这里尝试了以下代码: (查找捕获源筛选器) 当我在雅虎、MSN上编译
谢谢大家! 我在这里尝试了以下代码: (查找捕获源筛选器) 当我在雅虎、MSN上编译它时,它运行得很好,但它崩溃了AIM、Internet Explorer Flash摄像头、Firefox Flash摄像头和Skype。。。经过8次呼叫后,我在QueryInterface中找到了crash,我用了很多技巧跟踪它 现在我知道了,它在第8次呼叫时崩溃了 HRESULT CVCamStream::QueryInterface(refid-riid,void**ppv) 第八次呼叫,当它到达最后一次,我的意思是: 返回CSourceStream::QueryInterface(riid,ppv) 在第17行的Filters.cpp中 为什么你认为我会崩溃
感谢大家指导我找到正确的解决方案,即DirectShow,而不是驱动程序您无法决定其他程序如何调用您的驱动程序。大多数程序将使用DirectShow。有些人会使用win3.x技术VFW。许多新的程序,包括Windows XP的扫描仪和照相机向导,可能会通过WIA界面调用您。如果您不想实现所有这些,您需要通过WDM并让vfwwdm32.dll为您提供一个VFW接口,或者编写您自己的VFW驱动程序。Microsoft有几个API提供对图像数据的访问
- Twain:用于从扫描仪等捕获单个图像
- WIA:这似乎已经退化为一个单一的图像编解码器库
- VfW:一个非常古老的(Win16)API,它实际上只适用于视频文件编码/解码,但支持一些视频采集
- DirectShow:以前是DirectX SDK的一部分,现在是平台SDK的一部分。这是当前(通用)流媒体解决方案的最佳选择
- Windows Media/Media Foundation:这似乎更适合于视频播放/重新编码
- 特定于制造商的库:Pylon/Halcon/Imaging Control/
如何编写软件源设备: 您必须创建一个DirectShow筛选器,该筛选器至少提供一个输出引脚,并将其注册到VideoInputCategory下。某些应用程序可能需要从捕获应用程序获得多个接口,但这些接口取决于应用程序本身。用于尝试过滤器的简单应用程序是PlattformSDK中提供的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 );
....
#包括
#包括
const AMOVIESETUP_MEDIATYPE s_VideoPinType=
{
&MEDIATYPE_视频,//主要类型
&MEDIATYPE\u NULL//次要类型
};
常数AMOVIESETUP_引脚s_视频输出引脚=
{
L“Output”//Pin字符串名称
FALSE,//是否已渲染
TRUE,//这是一个输出吗
错,//我们能一个也没有吗
错,//我们能有很多吗
&CLSID_NULL,//连接到筛选器
NULL,//连接到pin
1,//类型数
&s\u VideoPinType//Pin详细信息
};
常数AMOVIESETUP_过滤器s_过滤器=
{
&CLSID\u MyFilter,//过滤器CLSID
L“bla”,//字符串名称
优点\u不使用,//筛选优点
1,//管脚编号
&s\u VideoOutputPin//Pin详细信息
};
regfilter2rf2;
rf2.dwVersion=1;
rf2.dwMerit=优点不使用;
rf2.cPins=1;
rf2.rgPins=s_Filter.lpPin;
HRESULT hr=pFilterMapper->RegisterFilter(CLSID\u MyFilter,\u FriendlyName.c\u str(),0,
&CLSID_VideoInputDeviceCategory,_InstanceID.c_str(),&rf2);
如果(失败(小时))
{
返回false;
}
std::wstring inputCat=GUIDToWString(CLSID\u VideoInputDeviceCategory);
std::wstring regPath=L“CLSID\\\”+inputCat+L“\\Instance”;
win32_utils::CRegKey hKeyInstancesDir;
LONG rval=openKey(HKEY_类_根、regPath、KEY_写、hKeyInstancesDir);
如果(rval==错误\成功)
{
win32_utils::CRegKey hKeyInstance;
rval=createKey(hKeyInstancesDir,_InstanceID,KEY_WRITE,hKeyInstance);
....
_InstanceID是为这个“虚拟设备”条目创建的GUID。你是指WDK而不是DDK,对吗?另外,为了更好地了解你在寻找什么,我在示例中找不到testcap。再一次,不要尝试编写驱动程序,因为驱动程序往往非常大。我将尝试查看我的代码以注册软件ware设备,并在此处显示。如果您真的必须使用windows驱动程序,请参阅,以获取有关如何与设备驱动程序通信的说明。祝您好运。如果您只是想避免一些崩溃,我在此处对这些内容进行了一点改进:(当然不是内核模式的摄像头,但可能有用)干杯!有关从C#内部执行此操作的相关文章,请回答