【问题标题】:How to set framerate for IMFSourceReader for webcam capture on Windows 10 laptop如何为 IMFSourceReader 设置帧速率以在 Windows 10 笔记本电脑上捕获网络摄像头
【发布时间】:2020-10-13 05:27:54
【问题描述】:

我已经看到了其他问题,但不知何故它不适合我。 环境:异步模式下的 Windows 10 MediaFoundation/SourceReader。Logitech C922 网络摄像头 1080p pro。

问题:

  1. 我正在尝试使用 sourcereader 在异步模式下使用媒体基础读取网络摄像头。我正在以 60-65 毫秒的频率调用 ::OnReadSample(),而不是预期的 30fps 的 33.33 毫秒。

  2. 验证人

hr = m_pReader->GetCurrentMediaType(
            (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 
            &pType
            );

并打印MF_MT_FRAME_RATE 为 30 x 1 的 pType 属性。MINMAX RANGE 也是 30 x 1。

  1. ::OnReadSample() 回调中验证了Mediatype 是否相同。未为 MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED 位设置流标志。所以 currentmediatype 在内部没有改变。
hr = m_pReader->GetCurrentMediaType(
                (DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, 
                &pt
                );
  1. 我已经设置了 fps,甚至使用 https://docs.microsoft.com/en-us/windows/win32/medfound/how-to-set-the-video-capture-frame-rate 上面页面上的确切功能,但仍然每 64 毫秒左右调用一次。 下面是正在使用的pType 的快照。
MF_MT_FRAME_SIZE    640 x 480
MF_MT_AVG_BITRATE   147456000
MF_MT_YUV_MATRIX    2
MF_MT_MAJOR_TYPE    MFMediaType_Video
MF_MT_VIDEO_LIGHTING    3
MF_MT_DEFAULT_STRIDE    1280
MF_MT_VIDEO_CHROMA_SITING   6
MF_MT_AM_FORMAT_TYPE    {F72A76A0-EB0A-11D0-ACE4-0000C0CC16BA}
MF_MT_FIXED_SIZE_SAMPLES    1
MF_MT_VIDEO_NOMINAL_RANGE   2
MF_MT_FRAME_RATE    30 x 1
MF_MT_PIXEL_ASPECT_RATIO    1 x 1
MF_MT_ALL_SAMPLES_INDEPENDENT   1
MF_MT_FRAME_RATE_RANGE_MIN  30 x 1
MF_MT_SAMPLE_SIZE   614400
MF_MT_VIDEO_PRIMARIES   2
MF_MT_INTERLACE_MODE    2
MF_MT_FRAME_RATE_RANGE_MAX  30 x 1
MF_MT_SUBTYPE   MFVideoFormat_YUY2

请提出在这种情况下可能缺少的内容。我有点得到 15fps 而不是要求的 30fps。我已经列举了设备的媒体类型,它支持 30fps。

提前致谢。

【问题讨论】:

  • 相机在低光照条件下产生的帧数可能会减少。尝试将其指向一些明亮的地方,以排除这种情况。
  • @RomanR。非常感谢。你说的对。确实这就是问题所在。当我在明亮的阳光照射区域进行测试时,我确实每 32-33 毫秒就会获得帧。这是我的期望..知道如何在弱光条件下强制获得 30fps 吗?
  • 我认为你不能在这种设备上锁定快门/曝光。您需要一个具有此功能的专用相机。您所看到的是延长曝光,这使得无法进行全帧速率。当您添加光线并制作相机以减少单个帧的曝光时间时,它可以达到 30 个。

标签: frame-rate ms-media-foundation webcam-capture


【解决方案1】:

这可能是因为您在 IMFSourceReader 而不是 IMFMediaSource 的处理程序上设置了调整后的媒体类型。

来自完整工作的example 的 sn-p 如下所示。请注意,定制的媒体类型设置为pSourceMediaTypeHandler 而不是pVideoReader。变量声明等参见示例源代码。

// ----- Set up webcam video source. -----

CHECK_HR(GetVideoSourceFromDevice(WEBCAM_DEVICE_INDEX, &pVideoSource, &pVideoReader),
"Failed to get webcam video source.");

CHECK_HR(pVideoReader->SetStreamSelection((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, TRUE),
"Failed to set the first video stream on the source reader.");

CHECK_HR(pVideoSource->CreatePresentationDescriptor(&pSourcePresentationDescriptor),
"Failed to create the presentation descriptor from the media source.");

CHECK_HR(pSourcePresentationDescriptor->GetStreamDescriptorByIndex(0, &fSelected, &pSourceStreamDescriptor),
"Failed to get source stream descriptor from presentation descriptor.");

CHECK_HR(pSourceStreamDescriptor->GetMediaTypeHandler(&pSourceMediaTypeHandler),
"Failed to get source media type handler.");

DWORD srcMediaTypeCount = 0;
CHECK_HR(pSourceMediaTypeHandler->GetMediaTypeCount(&srcMediaTypeCount),
"Failed to get source media type count.");

// ----- Attempt to set the desired media type on the webcam source. -----

CHECK_HR(MFCreateMediaType(&pWebcamSourceType), "Failed to create webcam output media type.");

CHECK_HR(FindMatchingVideoType(pSourceMediaTypeHandler, WEBCAM_PIXEL_FORMAT, VIDEO_WIDTH, VIDEO_HEIGHT, VIDEO_FRAME_RATE, pWebcamSourceType),
"No matching webcam media type was found.");

// This check is not necessary if the media type was from the list of supported types.
// It is useful if the media type is constructed manually. It is left here for demonstration purposes. 
CHECK_HR(pSourceMediaTypeHandler->IsMediaTypeSupported(pWebcamSourceType, &pWebCamMatchingType), "Webcam does not support requested options.");

if (pWebCamMatchingType != NULL) {
// If IsMediaTypeSupported supplied us with the closest matching media type use that.
CHECK_HR(pSourceMediaTypeHandler->SetCurrentMediaType(pWebCamMatchingType), "Failed to set media type on source.");
}
else {
// If IsMediaTypeSupported did not supply us a new type the typ checked must have been good enough use that.
CHECK_HR(pSourceMediaTypeHandler->SetCurrentMediaType(pWebcamSourceType), "Failed to set media type on source.");
}

CHECK_HR(pSourceMediaTypeHandler->GetCurrentMediaType(&pVideoSourceOutputType),
"Error retrieving current media type from first video stream.");

std::cout << "Webcam media type:" << std::endl;
std::cout << GetMediaTypeDescription(pVideoSourceOutputType) << std::endl << std::endl;

我使用该示例确认我能够将 Logitech C920 上的帧速率设置为 5fps,并在源读取器循环中获得正确的采样率。

Attempting to convert sample, sample duration 2000000, sample time 863168227222, evr timestamp 0.
Attempting to convert sample, sample duration 2000000, sample time 863170145312, evr timestamp 2000000.
Attempting to convert sample, sample duration 2000000, sample time 863172227244, evr timestamp 4000000.
Attempting to convert sample, sample duration 2000000, sample time 863174144901, evr timestamp 6000000.
Attempting to convert sample, sample duration 2000000, sample time 863176225938, evr timestamp 8000000.
Attempting to convert sample, sample duration 2000000, sample time 863178147388, evr timestamp 10000000.
Attempting to convert sample, sample duration 2000000, sample time 863180225543, evr timestamp 12000000.

【讨论】:

  • 感谢您的回复。请尝试更高的 fps,比如 30fps,然后观察相同的情况。作为罗曼。 R 表示,我的相同代码没有任何更改,在低光照条件下提供 15fps,在良好光照条件下提供 30fps。因此,网络摄像头似乎没有恒定的 fps,但也取决于光照条件。谢谢
猜你喜欢
  • 2023-03-10
  • 1970-01-01
  • 1970-01-01
  • 2017-11-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多