我想获取网络摄像头支持的所有FPS值的列表。
在How to Set the Video Capture Frame Rate msdn文章中,它说我可以向系统查询特定摄像机支持的最大和最小FPS。
它还说:
设备可能支持此范围内的其他帧速率。
在MF_MT_FRAME_RATE_RANGE_MIN中,它说:
不保证设备支持此范围内的每个增量。
所以听起来没有办法让Media Foundation中的相机获得所有支持的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,或者它在这方面真的受到限制?
答案 0 :(得分:3)
The frame rates and other attributes can be retrieved with code similar to the following (error checking omitted for brevity):
Microsoft::WRL::ComPtr<IMFSourceReader> reader = nullptr;
/* reader code omitted */
IMFMediaType* mediaType = nullptr;
GUID subtype { 0 };
UINT32 frameRate = 0;
UINT32 frameRateMin = 0;
UINT32 frameRateMax = 0;
UINT32 denominator = 0;
DWORD32 width, height;
DWORD index = 0;
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;
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.
Generally, denominator will be 1 (I have not seen it be anything else). And with the various webcams I have tested, frameRate, frameRateMin, and frameRateMax are the same number. The results will look nearly identical to what you listed above.
Edit:
For example, the following is the output of the code above (minus the printf) to a console output of the native formats that are supported for a Logitech Webcam Pro 9000:
This older webcam has 46 native formats, whereas newer webcams have many more (the C930e has 216). Here are the first 81 native formats of the C930e:
Sometimes a webcam will have very high numbers, which generally means that frames will not be throttled, and are delivered as quickly as possible, which is dependent on shutter speed, resolution, etc (I max this number to 99 for readability).
I think you are getting hung up on the following quote:
The device might support other frame rates within this range
However that is if the min and max do not equal the frame rate, and I have not seen webcams which vary in these numbers. Keep in mind that this can be used with any capture device. A 4 lane PCIe capture card has the bandwidth to keep up with almost whatever you want, so they would choose to write the driver accordingly (few formats with a large variance between min and max).