【问题标题】:IMFStreamSink::ProcessSample() not being called on a custom media sinkIMFStreamSink::ProcessSample() 未在自定义媒体接收器上调用
【发布时间】:2021-03-16 06:40:12
【问题描述】:

我正在尝试实现一个自定义 Windows Media Foundation 媒体接收器,以用于 UWP 应用程序,该应用程序将通过 MediaCapture::PrepareLowLagRecordToCustomSinkAsync() 使用它。

但是,我目前遇到了一个问题,即我的IMFStreamSinkProcessSample() 函数永远不会被调用,即使我在我的IMFMediaSink::OnClockStart() 中排队事件。

我已遵循此处的文档 (https://docs.microsoft.com/en-us/windows/win32/medfound/media-sinks) 并查看了“简单通信”示例。

这是我得到的输出,我记录了每个函数调用和接收器执行的每个调用的 HRESULT:

MyCaptureMediaSink::SetPresentationClock        
OK: Clock->AddClockStateSink(this)
MyCaptureStreamSink::BeginGetEvent        
OK: MediaEventQueue->BeginGetEvent(pCallback, punkState)
MyCaptureMediaSink::OnClockStart        
MyCaptureStreamSink::QueueEvent        
OK: MediaEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue)
OK: Sink->QueueEvent(MEStreamSinkStarted, GUID_NULL, S_OK, nullptr)
MyCaptureStreamSink::QueueEvent        
OK: MediaEventQueue->QueueEventParamVar(met, guidExtendedType, hrStatus, pvValue)
OK: Sink->QueueEvent(MEStreamSinkRequestSample, GUID_NULL, S_OK, nullptr)

我认为在最后一行之后我应该看到的是对 MyCaptureStreamSink::EndGetEvent() 的呼叫,因为收到了 MEStreamSinkStarted,然后是另一个 BeginGetEvent()EndGetEvent() 对和一个呼叫 ProcessSample(),因为下一个事件将是MEStreamSinkRequestSample 事件。

我是否遗漏了一些仍然需要调用才能让 MediaCapture 系统调用这些函数的函数?

【问题讨论】:

    标签: c++ uwp ms-media-foundation


    【解决方案1】:

    我找到了解决问题的方法: 我在不使用winrt::implements 的情况下重新实现了我的流接收器,这似乎按预期工作。我假设(尽管我仍然不是 100% 确定)正在发生的是,因为 IMFStreamSink 派生自 IMFMediaGeneratorwinrt::implemnets 不会为基本类型正确生成 QueryInterface。在我自己的实现中,我需要明确地处理它。

    这是旧的类声明,不起作用:

    class MyStreamSink : public winrt::implements<MyStreamSink, IMFStreamSink>
    {
        // ...
    };
    

    这是有效的类:

    class MyStreamSink: public IMFStreamSink
    {
        virtual HRESULT QueryInterface(const IID& riid, void** ppvObject) override
        {
            if (riid == __uuidof(IMFMediaEventGenerator))
            {
                *ppvObject = static_cast<IMFMediaEventGenerator*>(this);
            }
            //...
        }
    }
    

    【讨论】:

    • 可能是public winrt::implements&lt;MyStreamSink, IMFStreamSink, IMFMediaEventGenerator &gt;
    【解决方案2】:

    更好的方法是覆盖 winrt::is_guid_of。通过这种方法,您将获得一个共享的 v-table,而不是两个单独的 v-table。更多信息:How do I use C++/WinRT to implement a classic COM interface that derives from another classic COM interface

    template<>
    inline bool winrt::is_guid_of<IMFStreamSink>(guid const& id) noexcept
    {
        return winrt::is_guid_of<IMFStreamSink, IMFMediaEventGenerator>(id);
    }
    
    class MyStreamSink : public winrt::implements<MyStreamSink, IMFStreamSink>
    {
        //...
    };
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-12-10
      • 2014-04-26
      • 2020-12-12
      • 2014-10-15
      • 2015-01-10
      • 1970-01-01
      • 1970-01-01
      • 2019-02-15
      相关资源
      最近更新 更多