捕获视频数据到屏幕和文件

时间:2018-09-08 16:33:04

标签: ms-media-foundation

我正在编写一个尽可能简单的演示应用程序,该应用程序将从WebCam读取传入的数据并将其显示在屏幕上,并(可选地在按钮切换时)将视频流记录到磁盘上。为此,我实现了从WebCam(充当媒体源)到EVR(充当媒体接收器)的标准WMF管道体系结构。为了实现文件捕获功能,我修改了一个简单的MFT(FrameCounter MFT),如果接收器写入器对象可用,也将传入的样本写入接收器写入器。因此,所有数据都通过MFT从源传输到接收器,如果MFT可以使用Sink Writer,它也会将示例数据写入Sink Writer。

MFT进行原位处理,并在从其输出处理循环返回之前释放样品。在发生释放之前,对接收器写入器的写入仅在其WriteSample()调用中使用相同的输入示例。

问题在于此代码有效。我希望必须在MFT中复制该样本并将其提供给Sink Writer,以便它可以释放它。这引起了以下问题。

  1. 接收器编写器是否制作了自己的样本副本或对样本添加了自己的引用?它会释放给它的样品吗?据我了解,Sink Writer可以在编写样本之前将这些样本排队一段时间(如果需要的话)。 Sink Writers WriteSample()调用中对样本的一般处理是什么。

  2. 这是否只是偶然,现在是否可以为以后或速度较慢的计算机带来问题?上述技术有效吗?如果没有,推荐的方法是什么。我没有遇到任何奇怪的运行时错误。

  3. 我的印象是,当从网络摄像头捕获数据时,在写出样本之前,必须重新确定样本的时间戳。换句话说,写入的第一个样本的时间戳必须为​​0,然后根据该时间戳调整每个后续样本的时间戳。在这种情况下,这似乎不是必需的。是否需要重置此时基(曾经)?我注意到FileCapture演示中的示例代码会谨慎地执行此操作。 Microsoft是否已在最新版本中改进了Sink Writer来解决此问题?

我正在使用WMF.Net在C#中使用Windows 10。我意识到这可能是CLR及其垃圾收集的特例-但是,我将很感谢您可能提供的WMF见解(任何语言)。 Sink Writer的输出格式为H.264,如果需要的话。

1 个答案:

答案 0 :(得分:0)

1- Sink Writer并未真正记录其样本功能。为了提高效率,我认为它只是示例中的“ AddRef”。如果您在每次视频捕获后创建一个新样本,则只需在WriteSample之后将其释放。 Sink Writer不会有问题。

2-对于速度较慢的计算机,其工作原理相同。也许您必须删除样本以提高效率,但这与释放样本无关。

3- IMFSinkWriter文档中的WriteSample方法未明确告知是否需要采样时间/持续时间。所以我会说,如有必要,请设置它们。

编辑

我上面的解释是关于C ++的。 C#COM互操作是另一个故事。

我阅读了有关interop com的文章。似乎C#开发人员在调用Marshal.ReleaseComObject并重用它们之后没有将对象设置为nullptr。他们收到一个InvalidComObjectException。如果您像在C ++中那样,将AddRef,Release ans设置为NULL,我认为您不会有任何问题(RCW也在进行引用计数)。

对于使用托管代码重写COM对象的情况:

据我所知,

MediaFoundation组件是本机代码。我怀疑他们是否将它们更改为托管代码。即使发生这种情况,您也只需压制Marshal.ReleaseComObject,或者现在使用IsComObject。