OliverWaidler
OliverWaidler

Reputation: 31

IMFStreamSink::ProcessSample() not being called on a custom media sink

I am trying to implement a custom Windows Media Foundation media sink for use in a UWP application that will use it via MediaCapture::PrepareLowLagRecordToCustomSinkAsync().

However, I am currently running into an issue where the ProcessSample() function of my IMFStreamSink is never called, even though I queue the event in my IMFMediaSink::OnClockStart().

I have followed the documentation here ( https://learn.microsoft.com/en-us/windows/win32/medfound/media-sinks ) and also taken a look at the "Simple Communication" sample.

Here is the output that I am getting, I have logged every function call and the HRESULT of every call that my sinks execute:

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)

What I think I should be seeing after the last line is a call to MyCaptureStreamSink::EndGetEvent() due to MEStreamSinkStarted being received, followed by another BeginGetEvent() and EndGetEvent() pair and a call ProcessSample() because the next event would be the MEStreamSinkRequestSample event.

Am I missing some functions that I still need to call in order to get a call to these functions by the MediaCapture system?

Upvotes: 2

Views: 316

Answers (2)

Carl
Carl

Reputation: 1

An even better approach would be to override winrt::is_guid_of. By this approach you get one shared v-table and not two separate v-tables. For more information: 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>
{
    //...
};

Upvotes: 0

OliverWaidler
OliverWaidler

Reputation: 31

I have found the solution to my problem: I re-implemented my stream sink without using winrt::implements, which seems to work as intended. What I assume (I'm still not 100% sure, though) is happening is that since IMFStreamSink derives from IMFMediaGenerator, the winrt::implemnets does not generate the QueryInterface properly for the base type. In my own implementation, I need to explicitly handle it.

This is the old class declaration, which doesn't work:

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

and this is the class that works:

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

Upvotes: 1

Related Questions