我有一个自定义源,可以使用简单的拓扑。当 QueryInterface 被调用时,堆栈看起来像这样:
MySource.dll!MySource::QueryInterface(const _GUID & riid, void * * ppv) Line 83 C++
mfcore.dll!CMediaEventPtr::GetUnknown(struct IMFMediaEvent *,struct _GUID const &,void * *) Unknown
mfcore.dll!CMPSourceManager::OnNewStream() Unknown
mfcore.dll!CMPSourceManager::OnSourceEvent() Unknown
mfcore.dll!CMPSourceManager::OnSourceEventAsyncCallback::Invoke(struct IMFAsyncResult *) Unknown
使用相同的自定义源而不使用拓扑,让 IMFCaptureEngine 处理该问题。当 QueryInterface 被调用时,堆栈看起来像这样:
MySource.dll!MySource::QueryInterface(const _GUID & riid, void * * ppv) Line 42 C++
mfcore.dll!CMediaEventPtr::GetUnknown(struct IMFMediaEvent *,struct _GUID const &,void * *) Unknown
mfcore.dll!CSeqSourceWrap::HandleUpdatedStream(struct IMFMediaEvent *) Unknown
mfcore.dll!CSeqSourceWrap::OnSourceEvent() Unknown
mfcore.dll!CSeqSourceWrap::OnSourceEventAsyncCallback::Invoke(struct IMFAsyncResult *) Unknown
在 topo 情况下,我会调用 GetStreamDescriptor 和 RequestSample,一切正常。
MySourceCPP_COM.dll!MyStream::GetStreamDescriptor(IMFStreamDescriptor * * ppStreamDescriptor) Line 187 C++
mfcore.dll!CMPSourceManager::OnNewStream() Unknown
mfcore.dll!CMPSourceManager::OnSourceEvent() Unknown
mfcore.dll!CMPSourceManager::OnSourceEventAsyncCallback::Invoke(struct IMFAsyncResult *) Unknown
MySourceCPP_COM.dll!MyStream::RequestSample(IUnknown * pToken) Line 208 C++
mfcore.dll!CMPSourceNodeInfo::RequestSample() Unknown
mfcore.dll!CMPSourceNodeInfo::GenerateData() Unknown
mfcore.dll!CMPSourceNodeInfo::ProcessSample() Unknown
mfcore.dll!CMPWalker::ProcessCommands() Unknown
mfcore.dll!CMFMediaProcessor::ProcessSample() Unknown
mfcore.dll!CMFMediaProcessorStream::_RequestSample() Unknown
mfcore.dll!CMFMediaProcessorStream::RequestSample(struct IUnknown *) Unknown
mfcore.dll!CBitPump::HandleSinkRequestSample() Unknown
mfcore.dll!CBitPump::OnSinkEvent() Unknown
mfcore.dll!CBitPump::OnSinkEventAsyncCallback::Invoke(struct IMFAsyncResult *) Unknown
在 IMFCaptureEngine 的情况下,我从未接到任何一个调用,因此数据永远不会流动。 我发现唯一的区别是 CMPSourceManager 与 CSeqSourceWrap。
这是一个老问题,多年后答案仍然是“否”。
在此期间,微软推出了 Windows 11 虚拟相机 API 并允许添加自己的自定义视频源。即使在那里,这仍然令人沮丧地没有记录......
IMFCaptureEngine
视频源的情况更糟。 IMFCaptureEngine
的要求未知,显然它们还没有准备好使用普通的自定义实现,即使是上一段中的新 API 接受的实现也是如此。
当我们想要特定设备而不是由 API 或通过 API 选择时,我们应该提供
MFEnumDeviceSources
列举的来源之一。
扩展此行为的最佳方法是创建一个虚拟相机,然后通过 Stock API 的表示使用此 API 来使用它。或者,另一种方法是对 API 进行逆向工程并恢复对视频源的要求(如果可能的话)。