获取 Microsoft Media Foundation 中相机的所有支持的 FPS 值

Get all supported FPS values of a camera in Microsoft Media Foundation

我想获取我的网络摄像头支持的所有 FPS 值的列表。

How to Set the Video Capture Frame Rate msdn 文章中说我可以查询系统以获取特定相机支持的最大和最小 FPS。

它还说:

The device might support other frame rates within this range.

MF_MT_FRAME_RATE_RANGE_MIN 中说:

The device is not guaranteed to support every increment within this range.

所以听起来好像没有办法获得 所有 媒体基础中相机支持的 ​​FPS 值,只有最大值和最小值。

我知道 Linux v4l2-ctl --list-formats-ext 命令打印出更多支持的 FPS,而不仅仅是最小值和最大值。

这里只是 Linux 使用不同相机的几个例子:

$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
  Index       : 0
  Type        : Video Capture
  Pixel Format: 'YUYV'
  Name        : YUV 4:2:2 (YUYV)
    Size: Discrete 160x120
      Interval: Discrete 0.033s (30.000 fps)
      Interval: Discrete 0.036s (27.500 fps)
      Interval: Discrete 0.040s (25.000 fps)
      Interval: Discrete 0.044s (22.500 fps)
      Interval: Discrete 0.050s (20.000 fps)
      Interval: Discrete 0.057s (17.500 fps)
      Interval: Discrete 0.067s (15.000 fps)
      Interval: Discrete 0.080s (12.500 fps)
      Interval: Discrete 0.100s (10.000 fps)
      Interval: Discrete 0.133s (7.500 fps)
      Interval: Discrete 0.200s (5.000 fps)
    Size: Discrete 176x144
      Interval: Discrete 0.033s (30.000 fps)
      ...

$ v4l2-ctl --list-formats-ext
ioctl: VIDIOC_ENUM_FMT
    Index       : 0
    Type        : Video Capture
    Pixel Format: 'YUYV'
    Name        : YUV 4:2:2 (YUYV)
        Size: Discrete 640x360
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 640x480
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 320x240
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 160x120
            Interval: Discrete 0.033s (30.000 fps)
            Interval: Discrete 0.040s (25.000 fps)
            Interval: Discrete 0.050s (20.000 fps)
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 960x544
            Interval: Discrete 0.067s (15.000 fps)
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)
        Size: Discrete 1280x720
            Interval: Discrete 0.100s (10.000 fps)
            Interval: Discrete 0.200s (5.000 fps)

$ v4l2-ctl --list-formats-ext    
ioctl: VIDIOC_ENUM_FMT
        Index       : 0
        Type        : Video Capture
        Pixel Format: 'YUYV'
        Name        : YUV 4:2:2 (YUYV)
                Size: Discrete 1280x720
                        Interval: Discrete 0.111s (9.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 320x240
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x800
                        Interval: Discrete 0.111s (9.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)

        Index       : 1
        Type        : Video Capture
        Pixel Format: 'MJPG' (compressed)
        Name        : MJPEG
                Size: Discrete 1280x720
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 160x120
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 320x240
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 1280x800
                        Interval: Discrete 0.033s (30.000 fps)
                Size: Discrete 640x480
                        Interval: Discrete 0.033s (30.000 fps)

那么,有没有一种方法可以让 Microsoft Media Foundation 中的相机获得所有支持的 FPS,或者它在这方面真的很有限?

可以使用类似于以下的代码检索帧速率和其他属性(为简洁起见,省略了错误检查):

Microsoft::WRL::ComPtr<IMFSourceReader> reader = nullptr;
/* reader code omitted */

IMFMediaType* mediaType = nullptr;
GUID          subtype { 0 };

UINT32 frameRate    = 0u;
UINT32 frameRateMin = 0u;
UINT32 frameRateMax = 0u;
UINT32 denominator  = 0u;

DWORD index         = 0u;
DWORD width         = 0u;
DWORD height        = 0u;

HRESULT hr = S_OK;
while (hr == S_OK)
{
    hr = reader->GetNativeMediaType((DWORD) MF_SOURCE_READER_FIRST_VIDEO_STREAM, index, &mediaType);
    if (hr == MF_E_NO_MORE_TYPES)
        break;

    // Error checking omitted for brevity
    hr = mediaType->GetGUID(MF_MT_SUBTYPE, &subtype);
    hr = MFGetAttributeSize(mediaType, MF_MT_FRAME_SIZE, &width, &height);
    hr = MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE, &frameRate, &denominator);
    hr = MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE_RANGE_MIN, &frameRateMin, &denominator);
    hr = MFGetAttributeRatio(mediaType, MF_MT_FRAME_RATE_RANGE_MAX, &frameRateMax, &denominator);
    ++index;
}

The frame rate is expressed as a ratio. The upper 32 bits of the attribute value contain the numerator and the lower 32 bits contain the denominator. For example, if the frame rate is 30 frames per second (fps), the ratio is 30/1. If the frame rate is 29.97 fps, the ratio is 30,000/1001.

一般情况下,分母为1(我没见过其他的)。在我测试过的各种网络摄像头中,frameRate、frameRateMin 和 frameRateMax 都是相同的数字。结果看起来与您上面列出的几乎相同。

编辑:

例如,以下是上述代码(减去 printf)到 Logitech Webcam Pro 9000 支持的本机格式的控制台输出的输出:

这款较旧的网络摄像头有 46 种原生格式,而较新的网络摄像头有更多(C930e 有 216 种)。以下是 C930e 的前 81 种原生格式:

有时网络摄像头的数字非常高,这通常意味着帧不会被限制,并且会尽快传送,这取决于快门速度、分辨率等(我将这个数字最大设置为 99可读性)。

我认为您对以下引述很感兴趣:

The device might support other frame rates within this range

然而,如果最小值和最大值不等于帧速率,我还没有看到这些数字不同的网络摄像头。请记住,这可以与任何捕获设备一起使用。一个 4 通道 PCIe 采集卡的带宽几乎可以跟上你想要的任何东西,所以他们会选择相应地编写驱动程序(很少有格式在最小和最大之间有很大差异)。