Reputation: 31
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
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
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