C++ 虚拟网络摄像头驱动程序
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1627448/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Virtual Webcam Driver
提问by Franklin
I want to develop a virtual webcam driver which from User mode I'll pass image to it and it will display as webcam output.
我想开发一个虚拟网络摄像头驱动程序,从用户模式我将图像传递给它,它将显示为网络摄像头输出。
I don't want to use DirectX filter and CSourceStream etc. Because they don't work on some programs which doesn't use DirectX for capturing webcam image.
我不想使用 DirectX 过滤器和 CSourceStream 等。因为它们不适用于某些不使用 DirectX 捕获网络摄像头图像的程序。
I have to write a kernel mode device driver so.
我必须编写一个内核模式设备驱动程序。
Any ideas? I tried testcap from DDK samples, but it doesn't process image from user mode and doesn't get any input, just it displays 7 colors in webcam...
有任何想法吗?我从 DDK 样本中尝试过 testcap,但它不处理来自用户模式的图像,也没有得到任何输入,只是在网络摄像头中显示 7 种颜色......
Any help would be greatly appreciated. Thanks
任何帮助将不胜感激。谢谢
Thank you all!
谢谢你们!
I tried code from here: http://tmhare.mvps.org/downloads.htm(find Capture Source Filter)
我从这里尝试代码:http: //tmhare.mvps.org/downloads.htm(找到捕获源过滤器)
It worked well when I compiled it in Yahoo, MSN, but it crashed AIM, Internet Explorer Flash Webcam, Firefox Flash webcam and Skype... I got crash in QueryInterface after 8 time call to that, I found it with tracing it with a lot of tricks..
当我在雅虎、MSN 中编译它时它运行良好,但它崩溃了 AIM、Internet Explorer Flash 网络摄像头、Firefox Flash 网络摄像头和 Skype...8 次调用后,我在 QueryInterface 中崩溃了,我发现它用很多技巧。。
Now I know, it crashes on 8th call to HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv)
现在我知道了,它在第 8 次调用 HRESULT CVCamStream::QueryInterface(REFIID riid, void **ppv) 时崩溃
8th call when it reaches to last if, I mean: return CSourceStream::QueryInterface(riid, ppv);
当它到达最后一个时的第 8 个调用,我的意思是:返回 CSourceStream::QueryInterface(riid, ppv);
It's in 17th line of Filters.cpp
它在 Filters.cpp 的第 17 行
Why do you think I'm getting crash??
为什么你认为我会崩溃?
Thank you all for guiding me to find correct solution which is DirectShow, not driver
感谢大家指导我找到正确的解决方案,即 DirectShow,而不是驱动程序
回答by Christopher
There are several APIs from Microsoft which provide access to image data.
Microsoft 提供了多个 API 来提供对图像数据的访问。
- Twain: Used for single image capture from scanners, etc.
- WIA: This seems to have degenerated to a single image codec library.
- VfW: A very old (Win16) API which really works only Video-File encoding/decoding, but has support for some video acquisition.
- DirectShow: previously part in the DirectX SDK, currently in the Platform SDK. This is the place to go for current (general) streaming solutions.
- Windows Media/Media Foundation: This seems more to be geared at video playback/reencoding.
- Manufacturer Specific Libraries: Pylon/Halcon/Imaging Control/...
- Twain:用于从扫描仪等中捕获单个图像。
- WIA:这似乎已经退化为单个图像编解码器库。
- VfW:一个非常古老的 (Win16) API,它实际上只适用于视频文件编码/解码,但支持某些视频采集。
- DirectShow:以前在 DirectX SDK 中的一部分,目前在 Platform SDK 中。这是当前(通用)流媒体解决方案的理想去处。
- Windows Media/Media Foundation:这似乎更适合视频播放/重新编码。
- 制造商特定库:Pylon/Halcon/Imaging Control/...
DirectShow specific :
DirectShow 具体:
To create image acquisition devices under windows, you have to provide either a device (driver) which implements the streamclasses interfaces (or newer Avstream) or you have to write a usermode COM object which has to be added to the VideoInputCategory enumerator.
要在 Windows 下创建图像采集设备,您必须提供一个实现流类接口(或更新的 Avstream)的设备(驱动程序),或者您必须编写一个必须添加到 VideoInputCategory 枚举器的用户模式 COM 对象。
The Avstream sample provides everything for a real image acquisition device. Only the lower layer for the actual device really is missing.
Avstream 示例为真实图像采集设备提供了一切。只有实际设备的较低层确实丢失了。
If you can design a device, you should either create it DCAM or UVC compatible. For both there are built-in drivers supplied by windows.
如果您可以设计一个设备,您应该创建它兼容 DCAM 或 UVC。对于这两种情况,Windows 都提供了内置驱动程序。
How to write a software source device :
如何编写软件源设备:
You have to create a DirectShow filter which provides at least one output pin and register this under the VideoInputCategory. There may be several interfaces certain applications require from a capture application, but these depend on the application itself. Simple applications to try out filters are GraphEdit and AMCap which are supplied in the Plattform SDK.
您必须创建一个 DirectShow 过滤器,该过滤器提供至少一个输出引脚,并将其注册到 VideoInputCategory 下。某些应用程序可能需要从捕获应用程序获得多个接口,但这些取决于应用程序本身。试用过滤器的简单应用程序是 Plattform SDK 中提供的 GraphEdit 和 AMCap。
Some code :
一些代码:
#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 is a GUID created for this 'virtual device' entry.
_InstanceID 是为此“虚拟设备”条目创建的 GUID。
回答by u109919
You can not decide how other program would call your driver. Most of programs will use DirectShow. Some would use the win3.x technology VFW. Many new programs, including Windows XP's scanner and camera wizard, may call you via the WIA interface. If you do not want to implement all that, you need to at least provide the DirectShow interfacevia WDM and let vfwwdm32.dll gives you a VFW interface, or write your own VFW driver.
您无法决定其他程序如何调用您的驱动程序。大多数程序将使用 DirectShow。有些人会使用win3.x 技术VFW。许多新程序,包括 Windows XP 的扫描仪和相机向导,可能会通过 WIA 界面呼叫您。如果你不想实现所有这些,你至少需要通过 WDM提供 DirectShow 接口,让 vfwwdm32.dll 给你一个 VFW 接口,或者编写你自己的 VFW 驱动程序。