Windows 媒体基金会:IMFSourceReader::SetCurrentMediaType 执行时间问题
Windows Media Foundation: IMFSourceReader::SetCurrentMediaType execution time issue
我目前正致力于从视频捕获设备中检索图像数据。
对我来说重要的是我有一个相当特定格式的原始输出数据,我需要一个连续的数据流。因此我想使用 IMFSourceReader。我非常了解它是如何工作的。为了使整个管道正常工作,我检查了相机的输出格式并查看了可用的媒体基础转换 (MFT)。
这里的关键函数是IMFSourceReader::SetCurrentMediaType
。我想详细说明我发现的一个关键功能。如果我只是使用带有所需输出格式参数的函数,它会更改一些参数,如 fps 或分辨率,但调用会成功。当我第一次使用带有我想要的参数和 wrong 子类型(如 MJPG 或 sth.)的本机媒体类型调用该函数并使用我想要的参数和 [=25= 再次调用它时]correct 子类型调用成功,我最终得到了正确的参数。我怀疑这只有在合适的 MFT(解码器)可用时才是正确的。
到目前为止,我已经击败了 WMF,获得了我想要的东西。现在的问题是, IMFSourceReader::SetCurrentMediaType
的第二次调用需要很长时间。持续时间在很大程度上取决于所使用的相机。从 0.5s 到 10s 不等。老实说,我真的不知道为什么要花这么长时间,但我认为正确转换路径的计算 and/or 转换的初始化是问题所在。我发现过多地加载和卸载了相同的 dll(ntasn1.dll、ncrypt.dll、igd10iumd32.dll)。但是我自己加载一次并没有改变任何东西。
那么有人知道这个问题并且有快速解决方法吗?
或者有人知道解决方法:
- 在不使用
IMFSourceReader
的情况下通过媒体基础获取原始图像数据?
- Select 并自己加载转换,以支持源 reader 调用?
您基本上描述了 Source Reader 应该首先工作的方式。底层媒体源有自己的媒体类型,如果它需要适应请求的媒体类型和最接近的原始媒体类型,reader 可以提供转换。
视频捕获设备往往会公开许多 [本地] 媒体类型(我有一个网络摄像头,其中列举了 475 种!),因此如果格式适配不顺利,来源 reader 可能需要一些时间来尝试一种或另一种转换。
请注意,您可以通过像 MF_READWRITE_DISABLE_CONVERTERS
一样应用 certain attributes 来禁用源 reader 的转换,在这种情况下,无法直接在源上设置视频格式会导致失败。
您还可以读取原始设备格式的数据,并 decode/convert/process 通过将数据输入一个或一系列 MFT 来自己读取数据。通常,当您在源 reader 上设置相应格式时,源 reader 会为您管理 MFT。但是,如果您愿意,您也可以自己做。不幸的是,您无法为要管理的源 reader 构建 MFT 链。要么将其完全保留在源 reader 上,要么设置本机媒体类型,从 reader 中以原始格式读取数据,然后通过执行 IMFTransform::ProcessInput
管理您身边的 MFT ], IMFTransform::ProcessOutput
和朋友们。这不像来源 reader 那样容易,但是是可行的。
既然VuVirt不想写任何答案,我想为他和所有有同样问题的人添加一个。
在某些情况下,调用 IMFSourceReader::SetCurrentMediaType
会花费很长时间,因为目标格式是某种 RGB 格式并且本身不可用。所以为了摆脱它,我调整了我的图像管道以能够解释 YUV (YUY2)。我仍然不知道为什么会这样,但这对我来说是一项可行的工作。我不知道有什么其他方法可以加快通话速度。
附加提示:我发现通常有几个 IMFTransform 可以将许多本机可用的格式解码为 YUY2。所以,如果你能够使用 YUY2,你就是安全的。 NV12 是另一种可行的替代方案。虽然可能还有更多。
无论如何感谢您的回答
我目前正致力于从视频捕获设备中检索图像数据。 对我来说重要的是我有一个相当特定格式的原始输出数据,我需要一个连续的数据流。因此我想使用 IMFSourceReader。我非常了解它是如何工作的。为了使整个管道正常工作,我检查了相机的输出格式并查看了可用的媒体基础转换 (MFT)。
这里的关键函数是IMFSourceReader::SetCurrentMediaType
。我想详细说明我发现的一个关键功能。如果我只是使用带有所需输出格式参数的函数,它会更改一些参数,如 fps 或分辨率,但调用会成功。当我第一次使用带有我想要的参数和 wrong 子类型(如 MJPG 或 sth.)的本机媒体类型调用该函数并使用我想要的参数和 [=25= 再次调用它时]correct 子类型调用成功,我最终得到了正确的参数。我怀疑这只有在合适的 MFT(解码器)可用时才是正确的。
到目前为止,我已经击败了 WMF,获得了我想要的东西。现在的问题是, IMFSourceReader::SetCurrentMediaType
的第二次调用需要很长时间。持续时间在很大程度上取决于所使用的相机。从 0.5s 到 10s 不等。老实说,我真的不知道为什么要花这么长时间,但我认为正确转换路径的计算 and/or 转换的初始化是问题所在。我发现过多地加载和卸载了相同的 dll(ntasn1.dll、ncrypt.dll、igd10iumd32.dll)。但是我自己加载一次并没有改变任何东西。
那么有人知道这个问题并且有快速解决方法吗?
或者有人知道解决方法:
- 在不使用
IMFSourceReader
的情况下通过媒体基础获取原始图像数据? - Select 并自己加载转换,以支持源 reader 调用?
您基本上描述了 Source Reader 应该首先工作的方式。底层媒体源有自己的媒体类型,如果它需要适应请求的媒体类型和最接近的原始媒体类型,reader 可以提供转换。
视频捕获设备往往会公开许多 [本地] 媒体类型(我有一个网络摄像头,其中列举了 475 种!),因此如果格式适配不顺利,来源 reader 可能需要一些时间来尝试一种或另一种转换。
请注意,您可以通过像 MF_READWRITE_DISABLE_CONVERTERS
一样应用 certain attributes 来禁用源 reader 的转换,在这种情况下,无法直接在源上设置视频格式会导致失败。
您还可以读取原始设备格式的数据,并 decode/convert/process 通过将数据输入一个或一系列 MFT 来自己读取数据。通常,当您在源 reader 上设置相应格式时,源 reader 会为您管理 MFT。但是,如果您愿意,您也可以自己做。不幸的是,您无法为要管理的源 reader 构建 MFT 链。要么将其完全保留在源 reader 上,要么设置本机媒体类型,从 reader 中以原始格式读取数据,然后通过执行 IMFTransform::ProcessInput
管理您身边的 MFT ], IMFTransform::ProcessOutput
和朋友们。这不像来源 reader 那样容易,但是是可行的。
既然VuVirt不想写任何答案,我想为他和所有有同样问题的人添加一个。
在某些情况下,调用 IMFSourceReader::SetCurrentMediaType
会花费很长时间,因为目标格式是某种 RGB 格式并且本身不可用。所以为了摆脱它,我调整了我的图像管道以能够解释 YUV (YUY2)。我仍然不知道为什么会这样,但这对我来说是一项可行的工作。我不知道有什么其他方法可以加快通话速度。
附加提示:我发现通常有几个 IMFTransform 可以将许多本机可用的格式解码为 YUY2。所以,如果你能够使用 YUY2,你就是安全的。 NV12 是另一种可行的替代方案。虽然可能还有更多。
无论如何感谢您的回答