Windows 10 网络摄像头MJPG捕获流在Windows 10上不可用

Windows 10 网络摄像头MJPG捕获流在Windows 10上不可用,windows-10,webcam,directshow,video-capture,ms-media-foundation,Windows 10,Webcam,Directshow,Video Capture,Ms Media Foundation,在Windows 10 build 10.1607.14393.10(又名周年纪念版)上,我无法再获取MJPG捕获流。以前都是MJPG和YYY2的解决方案,现在我只在DirectShow(内核流)中获得YYY2,而在MediaFoundation MJPG中转换媒体类型到NV12方式之前,IbaseFieldS源连接到任何东西。在具有不同摄像头的多个系统上进行了尝试。你知道哪里不对吗 640x480 @30 YUY2 ... 640x480 @30

在Windows 10 build 10.1607.14393.10(又名周年纪念版)上,我无法再获取MJPG捕获流。以前都是MJPG和YYY2的解决方案,现在我只在DirectShow(内核流)中获得YYY2,而在MediaFoundation MJPG中转换媒体类型到NV12方式之前,IbaseFieldS源连接到任何东西。在具有不同摄像头的多个系统上进行了尝试。你知道哪里不对吗

     640x480   @30   YUY2
     ...
     640x480   @30   MJPG <- gone
 ...
DirectShow:
    com_t<IAMStreamConfig> sc;
    if_failed_return_result(camera_output_pin->QueryInterface(&sc));
    int number_of_capabilities = 0;
    int capability_size = 0;
    if_failed_return(sc->GetNumberOfCapabilities(&number_of_capabilities, &capability_size), -1);
    for (int i = 0; i < number_of_capabilities && k < count; i++) {
        VIDEO_STREAM_CONFIG_CAPS scc;
        assert(sizeof(scc) == capability_size);
        AM_MEDIA_TYPE* mt = null;
        if_failed_return(sc->GetStreamCaps(i, &mt, (BYTE*)&scc), -1);
...
640x480@30 YUY2
...
640x480@30 MJPG查询接口(&sc));
int number of_能力=0;
int-capability_-size=0;
如果返回失败(sc->GetNumberOfCapabilities(&NumberOfCapabilities,&CapabilitySize),-1);
对于(int i=0;i<功能的数量&&k<计数;i++){
视频流配置;
断言(sizeof(scc)=能力大小);
AM_媒体_类型*mt=null;
如果返回失败(sc->GetStreamCaps(i和mt,(字节*)和scc),-1);
...
在MMF中:

    640x480   @30   YUY2
    ...
    640x480   @30   NV12 // camera reports MJPG 4cc in USBView and KsStudio

for (int i = 0; k < count; i++) {
    com_t<IMFMediaType> type;
    if (d->reader->GetNativeMediaType(VIDEO_STREAM, i, &type) != 0) {
        break;
    }
    GUID guid_major_type = {0};
    if_failed_return_result(type->GetMajorType(&guid_major_type));
    if (guid_major_type == MFMediaType_Video) {
        GUID guid_subtype = {0};
        if_failed_return_result(type->GetGUID(MF_MT_SUBTYPE, &guid_subtype));
        AM_MEDIA_TYPE* amMediaType = null;
        if_failed_return_result(type->GetRepresentation(FORMAT_MFVideoFormat, (void**)&amMediaType));
        assert(amMediaType->cbFormat == sizeof(MFVIDEOFORMAT));
        const MFVIDEOFORMAT* mi = (const MFVIDEOFORMAT*)amMediaType->pbFormat;
640x480@30 YUY2
...
640x480@30 NV12//摄像机在USBView和KsStudio中报告MJPG 4cc
对于(int i=0;kreader->GetNativeMediaType(视频流、i和类型)!=0){
打破
}
GUID GUID_major_type={0};
如果失败,返回结果(类型->GetMajorType(&guid\U主类型));
如果(guid\u主类型==MFMediaType\u视频){
GUID GUID_子类型={0};
如果失败,返回结果(type->GetGUID(MF\u MT\u子类型和guid\u子类型));
AM_媒体_类型*amMediaType=null;
如果失败,则返回结果(type->GetRepresentation(FORMAT\u MFVideoFormat,(void**)和amMediaType));
断言(amMediaType->cbFormat==sizeof(MFVIDEOFORMAT));
常量MFVIDEOFORMAT*mi=(常量MFVIDEOFORMAT*)amMediaType->pbFormat;
作为

是的,MJPEG和H.264被解码/过滤是我们需要实现的一系列功能的结果,这一行为是在今年1月底左右计划、设计、测试并发布给我们的合作伙伴和Windows内部人士的。我们与合作伙伴合作,确保他们的应用程序在整个t他的变化,但我们在向你们传达这一变化方面做得很差。我们在这方面失球了,所以我想向你们所有人道歉

在Windows 10周年更新中,来自网络摄像头的MJPG视频由新的帮助服务“Windows Camera Frame Server”捕获,该服务自我介绍为“允许多个客户端从摄像头设备访问视频帧”。Mike M.也提到了这一点

例如,我无法看到多个客户端共享一个摄像头,因为TopoEdit的第二个实例给了我典型的错误:启动播放时出错。硬件MFT无法启动流媒体,因为缺少硬件资源

然而,MJPG和H264媒体类型确实被过滤掉了,因为平台更新现在声称有责任避免多个客户端同时访问同一个摄像头,并且每个客户端都独立解码,从而重复工作

Windows为您的应用程序解码MJPEG的主要原因之一是性能。随着Windows 10的周年更新,现在多个应用程序可以以以前不可能的方式访问摄像头。对我们来说,启用并发摄像头访问非常重要,所以Windows Hello,Microsoft Hololens和其他产品及功能可以可靠地假设相机在任何给定时间都可用,而不管其他应用程序可能正在访问它。导致MJPEG解码的原因之一是我们希望防止多个应用程序同时解码同一流,这将是重复的d的努力,从而造成不必要的性能损失

显然,这一“改进”让许多人大吃一惊

<>强>更新< /强>。通过创建如下定义的注册表值,可以检测到使用新的帧服务器特征的行为在系统范围内被禁用。一旦媒体基础API看到这个值,它就直接绕过帧服务器,选择一个原始代码路径与“硬件”(KS代理)对话。
  • 关键字名称:
    • HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows Media Foundation\Platform(64位应用程序;32位操作系统中的32位应用程序)
    • HKEY\U LOCAL\U MACHINE\SOFTWARE\WOW6432Node\Microsoft\Windows Media Foundation\Platform(64位操作系统中的32位应用程序)
  • 值名称:“EnableFrameServerMode”注册表项
  • 数值:0

既然这是答案,让我首先说明存在几种变通方法,从黑客到昂贵的开发

  • (hack)从原始Windows 10中获取旧的mfcore.dll,延迟与它的链接,并强制加载本地副本-这是hack,不要在家尝试,也不要发货
  • 使用缺乏文档记录的ksproxy.ax或它的现代替代品mfkproxy来实现您自己的层与摄像头对话
  • 将摄像头切换到WinUSB并使用libusb/libuvc(在Windows上的代码不是那么高,也不是那么成熟)并实现您自己的摄像头界面
  • 现在谈谈“框架服务器”的正确设计:

    在我们的zSpace系统设计中,我们还提供了帧服务器,该服务器可将图像解压缩、压缩摄像机馈送(其中四个摄像机的总速度接近每秒1Gpixel)、水滴检测信息和3D姿势三角测量结果发送给多个客户端(包括远程应用程序)同时,使用共享内存和/或套接字的整个过程只有几百行C代码。我已经实现了它,它可以在Windows和Linux上运行

    微软“改进”的不足之处在于忽视了客户的需求,我相信这很容易解决

    为了便于讨论,让我们假设摄影机流压缩格式(可以是MJPG/H.26x/HEVC/somethinew和better)

    假设有几种可能的客户机类型:

  • 克莱