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

Leo*_*Leo 2 webcam directshow video-capture ms-media-foundation windows-10

在 Windows 10 build 10.1607.14393.10(又称周年纪念版)上,我无法再获取 MJPG 捕获流。曾经是 MJPG 和 YUY2 分辨率,现在我在 DirectShow(内核流)和 Media Foundation MJPG 中仅获得 YUY2,然后在 IBaseFilter 源连接到任何内容之前将媒体类型转换为 NV12。尝试使用不同相机的多个系统。有什么想法可能是错的吗?

     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);
...
Run Code Online (Sandbox Code Playgroud)

在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;
Run Code Online (Sandbox Code Playgroud)

Rom*_* R. 6

正如Microsoft 的 Mike M 所解释的那样,

\n\n
\n

所以,是的,MJPEG 和 H.264 被解码/过滤掉是我们需要实现的一组功能的结果,这种行为是在 1 月底计划、设计、测试并发送给我们的合作伙伴和 Windows 预览体验成员的今年的。我们与合作伙伴合作,确保他们的应用程序在整个变更过程中继续正常运行,但我们在向大家传达这一变更方面做得很差。我们在这方面失败了,所以我\xe2\x80\x99d想向你们所有人表示歉意。

\n
\n\n

在 Windows 10 周年更新中,来自网络摄像头的 MJPG 视频由新的帮助服务“Windows Camera Frame Server”捕获,该服务自我介绍为“使多个客户端能够访问来自摄像头设备的视频帧”。Mike M 也提到过同样的情况。

\n\n

我无法看到多个客户端共享一台摄像机,因为 TopoEdit 的第二个实例给了我典型的错误:开始播放时出错。由于硬件资源不足,硬件 MFT 无法启动流式传输。

\n\n

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

\n\n
\n

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

\n
\n\n

显然,这种“改进”让很多人感到惊讶。

\n\n

更新。据检测,通过创建如下定义的注册表值,可以在系统范围内禁用使用新框架服务器功能的行为。一旦 Media Foundation API 看到该值,它就会选择原始代码路径直接绕过 Frame Server 与“硬件”(KS 代理)通信。

\n\n
    \n
  • 密钥名称:\n\n
      \n
    • HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows Media Foundation\\Platform(64 位应用程序;32 位操作系统中的 32 位应用程序)
    • \n
    • HKEY_LOCAL_MACHINE\\SOFTWARE\\WOW6432Node\\Microsoft\\Windows Media Foundation\\Platform(64 位操作系统中的 32 位应用程序)
    • \n
  • \n
  • 值名称:“EnableFrameServerMode”REG_DWORD
  • \n
  • 值:0
  • \n
\n