windows驱动开发8:虚拟摄像头方案

2023-11-03

一、摄像头框架

在业务场景中,有许多是需要应用能够通过摄像头的方式来访问相关的音视频数据,比如美颜、摄像头多路复用、IP摄像头接入视频会议等。这些功能通过虚拟摄像头的方式来实现,是一个比较通用的解决方案。那么如何及选用哪种技术方案来开发虚拟摄像头呢?本文从windows角度评估其相关技术可行性。

回到问题:应用操作虚拟摄像头,我们可以从Windows的应用是如何操作摄像头来评估。

Windows发展史上,主要使用了以下框架来操作摄像头:

  • VFW(Video Of Windows)这个是Windows最先使用的框架,也是最古老的,好处是接口函数够简单,在有些兼容或者小型用层场所用用也没什么问题。
  • DirectShow,这个是横跨 WINXP, WIN7,WIN8,WIN10都得到很好支持的框架,然而接口函数也挺复杂。
  • Media Foundation, 这个是WIN7之后,开发的新框架,目的是为了替换DirectShow,从而达到更好的性能和适应流媒体发展的需求。

二、应用现状

应用程序可以通过VFW、DirectShow、Media Foundation等一个或多个方式来操作摄像头。那么实际情况是如何的呢?

大量的操作摄像头的程序都是使用DirectShow框架,有小部分还在使用VFW框架。新近开发的程序或者对老版本程序的更新中,相当数量的程序使用Media Foundation框架代替了DirectShow。更有甚者,UWP框架的程序(就是Windows10平台新出来的,为了 “大一统“ 目的,这个目前也是小众,能否发展做大谁知道),对驱动级别的摄像头限制更大,已经不再支持老内核流框架。

所以,摄像头应用框架选择现状为:

  • VFW:较少,一些古老的应用
  • DirectShow:大量,慢慢迁移到Media Foundation
  • Media Foundation:大量
  • UWP:Win10应用,如Camera、Skype等

三、虚拟摄像头

3.1 应用层方式
应用框架 方案 实现案例
VFW
DirectShow ksproxy.ax OBS-VirtualCam,C++
Media Foundation MFCreateVirtualCamera(win11) https://github.com/microsoft/Windows-Camera,C#
Media Foundation IMFMediaSource(Vista)
3.2 驱动方式

1、VFW:Video for Windows,是一种趋于废弃的windows驱动模型。指Microsoft推出的关于数字视频的一个软件开发包,VFW的核心是AVI文件标准。围绕AVI文件,VFW推出了一整套完整的视频采集、压缩、解压缩、回放和编辑的应用程序接口。发展趋势:VFW(95) → WDM(98/2000/xp) → WDF(xp之后)。

2、UVC:USB Video Class,USB视频类,是一种为USB视频捕获设备定义的协议标准。是Microsoft与另外几家设备厂商联合推出的为USB视频捕获设备定义的协议标准,已成为USB org标准之一。事实上最新版本windows中,UVC自动加载usbvideo.sys,器内部也是使用ks.sys,即也是使用下面的Kernel Stream流驱动框架。参考:USB 视频类 (UVC) 相机实现指南

3、Kernel Streaming:内核流式传输 (KS) 指的是 Microsoft 提供的服务,支持对流式数据进行内核模式处理。Microsoft 提供了三种多媒体类驱动程序模型: port class、stream class和 AVStream。这些类驱动程序在系统文件 portcls.sys、 stream.sys和 ks.sys中 (内核模式 dll) 的导出驱动程序实现。 在 Windows XP 和更高版本中, ks.sys称为 AVStream。

4、AVStream:是Kernel Streaming三种多媒体驱动模型之一,也是最新版本模型,包含了音视频的部分。在 AVStream 驱动程序模型中,供应商提供与 Microsoft 提供的类驱动程序交互的微型驱动程序,如下图所示。
在这里插入图片描述

5、Windows USB摄像头驱动程序栈架构
在这里插入图片描述

从上面的图可以看到,厂商只提供硬件和固件,并且这个固件应该满足UVC规范,而其余的由Windows系统包圆了。其中ks.sys与AVStream、portclass.sys之间的关系如下:

  • AVStream是ks.sys中的一部分,而ks.sys是其上层驱动。
  • ks.sys的下层可以是portclass.sys实现的音频类,也可以是USB实现的音视频类。
  • ks.sys文件中包含了全部的ks功能和AVStream功能

6、方案对比

驱动框架 说明 实现案例
VFW 过时的技术,不推荐
UVC 实现USB摄像头驱动 e2esoft的VCam
Kernel Stream:Port Class 主要是音频
Kernel Stream:Stream Class 主要是视频,参考:Stream Class
Kernel Stream:AVStream 音视频最新驱动框架,参考:AVStream avshws、avscamera
3.3 方案对比
类别 方案 平台兼容 应用兼容 实现难度 是否可以开关 是否需要管理员权限
应用层 direct show >=98 一般
mfd- MFCreateVirtualCamera >=win11 一般 创建、销毁需要
mfd - IMFMediaSource >=vista 一般 较难
驱动层 VFW >=95 一般 安装需要
UVC >= xp sp2 最好 最难 安装需要
KS - Stream Class >= xp 一般 较难 安装需要
KS - AVSteam >= xp 较好 较难 安装需要

四、总结在这里插入图片描述

如上图所示,无论应用层以哪种方式操作摄像头,最终都会汇聚于Kernel Streaming驱动层,而Kernel Streaming对于USB摄像头又依赖于UVC驱动。所以总结如下:

  • 目前市面大部分应用操作摄像头使用DirectShow、Media Foundation框架,win10微软应用只支持UWP。从兼容层面看只有UVC、AVSteam两类驱动框架开发的虚拟摄像头才可以完全兼容。
  • UVC由于在更底层,可以适配未来windows的版本变化,但开发难度极高;AVSteam在没有新的流媒体驱动框架出现前,是可以满足所有应用兼容,开发难度相对较好。

综上,建议选择AVSteam驱动框架开发虚拟摄像头

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

windows驱动开发8:虚拟摄像头方案 的相关文章

  • 如何解决内存碎片

    我们偶尔会遇到这样的问题 长时间运行的服务器进程 在 Windows Server 2003 上运行 由于内存分配失败而引发异常 我们怀疑这些分配由于内存碎片而失败 因此 我们一直在寻找一些可能对我们有帮助的替代内存分配机制 我希望有人能告
  • 设置 Form.KeyPreview = true 的缺点?

    我想知道 Form KeyPreview 属性实际上有什么用处 它为什么存在以及将其设置为 true 会带来什么 风险 我想它一定有some负面影响 否则它根本不应该存在 或者至少默认情况下是正确的 EDIT 我很清楚what确实如此 我问
  • C# - 方法必须有返回类型

    我在调用 C 中的方法时遇到问题 不断收到消息 方法 计算 必须有返回类型 using System Diagnostics namespace WindowsFormsApplication1 public partial class F
  • 如何在Windows上模拟socket.socketpair

    标准Python函数套接字 套接字对 https docs python org 3 library socket html socket socketpair不幸的是 它在 Windows 上不可用 从 Python 3 4 1 开始 我
  • 需要 TensorFlow 依赖项。如何在 Windows 上运行 TensorFlow

    我有兴趣让 TensorFlow 在 Windows 上运行 但目前我意识到这是不可能的 因为某些依赖项无法在 Windows 上使用 例如巴泽尔 之所以出现这种需求 是因为据我目前了解 从 TensorFlow 访问 GPU 的唯一方法是
  • Qt 支持 Windows 蓝牙 API 吗?

    谁能告诉我 Qt 是否支持 Windows 蓝牙 API 如果是这样 您能否分享一些有关如何使用它的信息 自上次答复以来 这个问题的答案发生了一些变化 Qt 5 2 版为 Linux BlueZ 和 BlackBerry 设备实现了蓝牙 A
  • 在哪里可以获得 PHP 5.3+ 的 runkit DLL 扩展?

    这是一个简单的问题 我在哪里可以获得 PHP 5 3 版本的 runkit 扩展 它的手册 http php net manual en book runkit php http php net manual en book runkit
  • 如何为最终用户方便地启动Java GUI程序

    用户想要从以下位置启动 Java GUI 应用程序Windows 以及一些额外的 JVM 参数 例如 javaw Djava util logging config file logging properties jar MyGUI jar
  • teracopy 如何替换默认的 Windows 副本

    我问了这个问题Windows 文件复制内部结构 动态加密 https stackoverflow com questions 24220382 windows file copy internals on the fly encryptio
  • Windows 目录永远不会包含临时文件的非 ASCII 字符?

    在 Windows 上使用 MinGW 7 3 0 由于 Windows 限制 Hunspell 无法从包含非 ASCII 字符的位置加载字典文件 我已经尝试了所有方法 1 现在我将文件复制到没有 ASCII 字符的路径 然后再将其交给 H
  • 将所有文件与指定目录(和子目录)中的所有文件进行二进制比较

    我需要将目录及其子目录中包含的所有文件与同一目录及其子目录中包含的所有其他文件进行比较 并将匹配文件的路径记录到文本文件或 CSV 我意识到有一些软件工具可以做到这一点 但除非它可以在 Windows 中开箱即用 否则我将不被允许在我的网络
  • 为什么我在 Windows 上使用 async 和 wait 时会收到 NotImplementedError 错误?

    我有这个代码 import os import time import asyncio async def run command args Example from http asyncio readthedocs io en lates
  • Windows 10 上的 LibPNG 构建问题

    我试图在 Windows 10 上构建 libpng 以获取 win32 二进制文件 但我认为有一个与 awk 解析带有 CRLF 行结尾的文件相关的问题 我尝试使用 dos2unix 命令转换文件 但没有成功 结果相同 在 make 命令
  • 如何迭代所有注册表项?

    我正在尝试迭代所有注册表项以查找 包含 并删除 jre1 5 0 14 值 有办法做到吗 下面的代码只是在特定键下找到jre1 5 0 14 我确实想迭代所有的键 顺便说一句 if 子句获取是否等于 jre1 5 0 14 但如果它包含 j
  • 将 value 转换为 bool 的魔法

    今天我意识到将值转换为 bool 是一种魔法 int value 0x100 unsigned char uc static cast
  • Mac OS X 上的 /proc/self/cmdline / GetCommandLine 等效项是什么?

    如何在不使用 argc argv 的情况下访问 Mac OS X 上的命令行 在 Linux 上 我会简单地阅读 proc self cmdline or use GetCommandLine在 Windows 上 但我找不到 Mac OS
  • SetWindowsHookEx 函数返回 NULL

    我正在研究 DLL 注入 但收到错误如下 挂接进程失败 87 参数不正确 目标进程和dll都是64位的 注入代码为 BOOL HookInjection TCHAR target TCHAR dll name https msdn micr
  • 将 OpenBLAS 链接到 MinGW

    我正在尝试链接OpenBLAS https www openblas net 图书馆与明GW w64 https mingw w64 org Windows 上的编译器 这是我的代码 include
  • 从 Powershell 脚本安装 Python

    当以管理员身份从 PowerShell 命令行运行以下命令时 可以在 Windows 11 上成功安装 Python c temp python 3 11 4 amd64 exe quiet InstallAllUsers 0 Instal
  • 如果我使用客户端计算机上未安装的字体,会发生什么情况?

    有人可以告诉我 如果我在 WinForms 应用程序中使用目标计算机上不可用的字体 会发生什么情况 它是否使用同一系列的字体 只是 Sans Serif 还是其他字体 您的应用程序将回退到 Segoe UI Tahoma 然后是 MS Sa

随机推荐

  • LeetCode-1832. 判断句子是否为全字母句【哈希表,位运算】

    LeetCode 1832 判断句子是否为全字母句 哈希表 位运算 题目描述 解题思路一 用数组记录 一次遍历 解题思路二 位运算 最终判断mask是否为26个1即 1 lt lt 26 1 解题思路三 0 题目描述 全字母句 指包含英语字
  • vue项目页面添加水印

    vue项目页面添加水印 使用方法 在根组件中全局引入 watermark set 用户名 页面显示效果如下 方法如下 let watermark let setWatermark str gt let id 1 23452384164 12
  • python_error

    inspection info This inspection detects code which can not be normally reached 检验信息 本次检验检测到正常情况下无法达到的代码 inspection info
  • Spring、SpringMVC、SpringBoot三者的区别

    目录 Spring是什么 SpringMVC是什么 SpringBoot是什么 Spring SpringMVC SpringBoot三者之间的关系 Spring是什么 Spring是一个开源的应用程序框架 它提供了一种简易的开发方式 通过
  • 《MATLAB 神经网络43个案例分析》:第40章 动态神经网络时间序列预测研究——基于MATLAB的NARX实现

    MATLAB 神经网络43个案例分析 第40章 动态神经网络时间序列预测研究 基于MATLAB的NARX实现 1 前言 2 MATLAB 仿真示例 3 小结 1 前言 MATLAB 神经网络43个案例分析 是MATLAB技术论坛 www m
  • 一篇文章读懂少儿机器人编程课程学什么?

    少儿机器人编程课程都学习什么 可以说在少儿成长阶段 孩子想接触的各式各样的主题和对生活的感性认知 通过机器人编程课程都可以学习到 以贝尔机器人编程课程为例 在锻炼孩子们逻辑思维能力的同时 会结合生活观察 启发思考 精细动作等训练 拓展生物
  • 服务器root权限安全策略配置

    服务器root权限安全策略配置 linux系统中 root具有至高无上的权限 为了安全起见 项目生产环境一般会要求禁止root用户直接ssh登录 使用普通用户登录 有特殊需求时 特定组用户可以使用su切换到root用户 或sudo切换到ro
  • 关于wait/notify以及顺序打印

    1 等待和唤醒是同一个对象 2 notify只会唤醒一个线程 使用角度 1 Object wait 会抛出 InterruptedException 2 调用object wait 必须首先对object monitor lock 进行加锁
  • 2020.12.6-参加中国电子学会的青少年软件编程等级考试C语言5级(良好通过)

    Jensen今天参加了中国电子学会的青少年软件编程等级考试C语言的5级考试 目前C语言的5级是最高级别 需要将基本算法都学完的孩子来参加 基本算法包括递推 递归 贪心 分治 搜索 动态规划等 Jensen 两道题AC 其他两道题没有AC 但
  • 机器学习:马尔可夫模型

    后续遇到合适的案例会再补充 1 马尔可夫模型 马尔可夫模型 Markov Model MM 是一种统计模型 广泛应用在自然语言处理等领域中 1 1 数学定义 考虑一组随机变量序列 X X 0
  • Android获取手机联系人的基本信息(如姓名、电话、邮箱、备注)

    在做项目的过程中 需要获取我们手机通讯录联系人的基本信息 如姓名 电话 邮箱 备注 昵称 公司 职位 家庭电话等等信息 下面就是我总结的一些具体方法 1 首先读取联系人需要添加读取权限 6 0以上需要动态获取权限 1 1AndroidMan
  • go context用法详解

    转发自 作者kingeasternsun https studygolang com articles 10155 fr sidebar 本文主要基于官方文档Go Concurrency Patterns Context以及视频Advanc
  • SpringBoot+Vue校园学习成绩管理系统

    简介 本项目采用了基本的springboot vue设计的校园学习成绩管理系统 详情请看截图 经测试 本项目正常运行 本项目适用于Java毕业设计 课程设计学习参考等用途 项目描述 项目名称 SpringBoot Vue校园学习成绩管理系统
  • Hyperledger Fabric 带入门 Python 课程

    Hyperledger Fabric 带入门 Python 课程 Hyperledger Fabric 是一个开源的区块链框架 被广泛应用于企业级联盟链场景 Python 是一种高级编程语言 易于学习和使用 是区块链领域的热门语言之一 本文
  • 数字表达_金字塔神秘数字之谜!142857这组神奇的数字表达着什么含义

    在埃及金字塔内 发现一组看似平凡 但很神奇的数字 142857 这组数字背后隐藏着人类无法解释的谜团 有人说这组数字和汶川大地震的时间偶合 这组数字隐藏了灾难发生的预言之秘 这到底是有心人无端的揣测 还是严谨的科学推论 142857这组数字
  • c++ list 容器splice函数

    list 的splice函数主要是用来合并两个list splice是list中特有的拼接方法 splice实现了不需要拷贝的list合并 即可以在常数时间内从list的一个区域拼接到另一个list的一个区域 也就是说splice是一个常数
  • ParallelLoopState.Break与ParallelLoopState.Stop区别

    ParallelLoopState Break与ParallelLoopState Stop区别 Break和Stop都是为了停止循环的一种手段 不同之处在于 Break不立马结束循环 而是要等所有小于ParallelLoopState L
  • shell脚本中调用java程序,并传递参数的方法

    为了方便运行多个java程序 选择写了脚本进行统一管理 简单介绍下传输参数的方法 假设要向file java传输参数 step1 需要先生成 class文件 javac Test java step2 在脚本中定义参数 int a 5 do
  • 拉格朗日插值多项式

    1 拉格朗日插值多项式 首先给出 n次插值基函数定义 若 n 次 多 项 式 l j
  • windows驱动开发8:虚拟摄像头方案

    一 摄像头框架 在业务场景中 有许多是需要应用能够通过摄像头的方式来访问相关的音视频数据 比如美颜 摄像头多路复用 IP摄像头接入视频会议等 这些功能通过虚拟摄像头的方式来实现 是一个比较通用的解决方案 那么如何及选用哪种技术方案来开发虚拟