我对 Windows Media Foundation API 非常陌生。我尝试创建一个可以显示和操作摄像机视频输入流的程序。
我使用 Media Foundation 进行视频流读取,支持的颜色格式是 NV12,所以我必须将其转换为 RGB 或 ARGB 才能创建OpenGL纹理对象。
我尝试在CPU端使用纯c++代码来做到这一点,但性能非常糟糕。然后我尝试使用IMFTranform
进行颜色转换,性能非常好,但是我遇到了一个奇怪的问题。
IMFTransform::Process
返回 S_OK
,但我不断收到卡住的图像输出。结果图像像素不实时更新,持续多帧卡住,且卡住时间越来越长。如果我使用纯 C++ 代码进行颜色转换,那么一切都会正常工作。
这是我的代码,https://gist.github.com/zhiqiang-li/16d1a6a1b00e8fb39847c8ca323b5604 。请让我知道您认为我做错了什么。
最佳答案
您是否尝试让 SourceReader 为您进行转换:
hr = mAttributes->SetUINT32(MF_READWRITE_DISABLE_CONVERTERS, FALSE);
By default, the source reader and sink writer can perform some format conversions on uncompressed audio and video streams. To disable this behavior, set this attribute to TRUE when you create the source reader or sink writer.
默认情况下它是 FALSE,因此您实际上不需要显式设置此属性。
然后:
hr = mSourceReader->SetCurrentMediaType((DWORD)MF_SOURCE_READER_FIRST_VIDEO_STREAM, NULL, mediaType);
与:
mOutputMediaType->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_NV12);
同时根据NV12格式计算图像尺寸(MF_MT_FRAME_SIZE)。不要设置 MF_MT_DEFAULT_STRIDE,SourceReader 会为您完成此操作。
所以我们的想法是从 SourceReader 获取 NV12 格式,即使捕获源提供 RGB32 格式。 SourceReader 通常能够做到这一点。
关于camera - IMFTransform 隐蔽相机流颜色格式,IMFTransform::ProcessOutput 返回卡住图像数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55326266/