我正在编写一个简单的可能的演示应用程序,它从WebCam读取传入的数据,并将其显示在屏幕上(并且可选地在按钮的切换处)将视频流记录到磁盘。为此,我实现了WebCam的标准WMF管道架构,该架构充当EVR的媒体源,EVR充当媒体接收器。为了实现文件捕获功能,我修改了一个简单的MFT(FrameCounter MFT),如果Sink Writer对象可用,还将传入的样本写入Sink Writer。因此,所有数据都通过MFT从源传输到接收器,如果MFT可以使用Sink Writer,它也会将样本数据写入Sink Writer。
MFT就在处理并从输出处理循环返回之前释放样本。在发布发布之前,对接收器写入器的写入仅在其WriteSample()调用中使用相同的输入样本。
问题是这段代码有效。我希望必须在MFT中制作样本的副本并将其提供给Sink Writer以便它可以释放它。这提出了以下问题......
我正在使用WMF.Net在C#上使用Windows 10。我意识到这可能是CLR及其垃圾收集的一个特例 - 但是,我将非常感谢您可能提供的任何WMF见解(使用任何语言)。 Sink Writer输出格式是H.264 - 如果重要的话。
1- Sink Writer没有真正记录它对样本的作用。为了提高效率,我想它只是样本上的“AddRef”。如果您在每次视频捕获后创建新样本,则只需在WriteSample之后释放它。 Sink Writer没有问题。
2-对于较慢的机器,它的工作原理相同。也许你必须放弃样品以提高效率,但它与释放样品无关。
3- IMFSinkWriter文档中的WriteSample方法未明确告知是否需要采样时间/持续时间。所以我想说,必要时设置它们。
编辑
我上面的解释是关于C ++的。 C#COM互操作是另一个故事。
我读了关于interop com的文章。在调用Marshal.ReleaseComObject之后,C#开发人员似乎没有将对象设置为nullptr,并重用它们。它们收到InvalidComObjectException。如果AddRef,Release ans设置为NULL,就像在C ++中一样,我认为你不会有问题(RCW也在进行引用计数)。
对于在托管代码中重写COM对象的情况:
据我所知,MediaFoundation组件是本机代码。我怀疑他们是否将其更改为托管代码。即使它发生了,你只需要压制Marshal.ReleaseComObject,或者现在使用IsComObject。