From 2d4387c1f5ce12010cea48402a7a26bfab55fb5c Mon Sep 17 00:00:00 2001 From: Nikolay Sivov Date: Tue, 11 Jun 2019 15:40:04 +0300 Subject: [PATCH] mf: Add support for IMFSampleGrabberSinkCallback2. Signed-off-by: Nikolay Sivov Signed-off-by: Alexandre Julliard --- dlls/mf/samplegrabber.c | 42 ++++++++++++++++++++++++++++++++++------- include/mfidl.idl | 17 +++++++++++++++++ 2 files changed, 52 insertions(+), 7 deletions(-) diff --git a/dlls/mf/samplegrabber.c b/dlls/mf/samplegrabber.c index 9cf94654e53..7bc566f542a 100644 --- a/dlls/mf/samplegrabber.c +++ b/dlls/mf/samplegrabber.c @@ -66,6 +66,7 @@ struct sample_grabber_stream LONG refcount; struct sample_grabber *sink; IMFMediaEventQueue *event_queue; + IMFAttributes *sample_attributes; enum sink_state state; struct list items; IUnknown *cancel_key; @@ -79,6 +80,7 @@ struct sample_grabber IMFMediaEventGenerator IMFMediaEventGenerator_iface; LONG refcount; IMFSampleGrabberSinkCallback *callback; + IMFSampleGrabberSinkCallback2 *callback2; IMFMediaType *media_type; BOOL is_shut_down; struct sample_grabber_stream *stream; @@ -90,6 +92,11 @@ struct sample_grabber CRITICAL_SECTION cs; }; +static IMFSampleGrabberSinkCallback *sample_grabber_get_callback(const struct sample_grabber *sink) +{ + return sink->callback2 ? (IMFSampleGrabberSinkCallback *)sink->callback2 : sink->callback; +} + struct sample_grabber_activate_context { IMFMediaType *media_type; @@ -209,6 +216,8 @@ static ULONG WINAPI sample_grabber_stream_Release(IMFStreamSink *iface) IMFMediaEventQueue_Shutdown(stream->event_queue); IMFMediaEventQueue_Release(stream->event_queue); } + if (stream->sample_attributes) + IMFAttributes_Release(stream->sample_attributes); LIST_FOR_EACH_ENTRY_SAFE(item, next_item, &stream->items, struct scheduled_item, entry) { stream_release_pending_item(item); @@ -333,8 +342,16 @@ static HRESULT sample_grabber_report_sample(struct sample_grabber *grabber, IMFS if (SUCCEEDED(hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &size))) { - hr = IMFSampleGrabberSinkCallback_OnProcessSample(grabber->callback, &major_type, flags, sample_time, - sample_duration, data, size); + if (grabber->callback2) + { + hr = IMFSample_CopyAllItems(sample, grabber->stream->sample_attributes); + if (SUCCEEDED(hr)) + hr = IMFSampleGrabberSinkCallback2_OnProcessSampleEx(grabber->callback2, &major_type, flags, + sample_time, sample_duration, data, size, grabber->stream->sample_attributes); + } + else + hr = IMFSampleGrabberSinkCallback_OnProcessSample(grabber->callback, &major_type, flags, sample_time, + sample_duration, data, size); IMFMediaBuffer_Unlock(buffer); } @@ -814,7 +831,10 @@ static ULONG WINAPI sample_grabber_sink_Release(IMFMediaSink *iface) if (!refcount) { - IMFSampleGrabberSinkCallback_Release(grabber->callback); + if (grabber->callback) + IMFSampleGrabberSinkCallback_Release(grabber->callback); + if (grabber->callback2) + IMFSampleGrabberSinkCallback2_Release(grabber->callback2); IMFMediaType_Release(grabber->media_type); if (grabber->event_queue) { @@ -941,7 +961,8 @@ static HRESULT WINAPI sample_grabber_sink_SetPresentationClock(IMFMediaSink *ifa EnterCriticalSection(&grabber->cs); - if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnSetPresentationClock(grabber->callback, clock))) + if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnSetPresentationClock(sample_grabber_get_callback(grabber), + clock))) { if (grabber->clock) { @@ -1008,7 +1029,7 @@ static HRESULT WINAPI sample_grabber_sink_Shutdown(IMFMediaSink *iface) EnterCriticalSection(&grabber->cs); grabber->is_shut_down = TRUE; - if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnShutdown(grabber->callback))) + if (SUCCEEDED(hr = IMFSampleGrabberSinkCallback_OnShutdown(sample_grabber_get_callback(grabber)))) { IMFMediaSink_Release(&grabber->stream->sink->IMFMediaSink_iface); EnterCriticalSection(&grabber->stream->cs); @@ -1246,6 +1267,9 @@ static HRESULT sample_grabber_create_stream(struct sample_grabber *sink, struct if (FAILED(hr = MFCreateEventQueue(&object->event_queue))) goto failed; + if (FAILED(hr = MFCreateAttributes(&object->sample_attributes, 0))) + goto failed; + *stream = object; return S_OK; @@ -1277,8 +1301,12 @@ static HRESULT sample_grabber_create_object(IMFAttributes *attributes, void *use object->IMFClockStateSink_iface.lpVtbl = &sample_grabber_clock_sink_vtbl; object->IMFMediaEventGenerator_iface.lpVtbl = &sample_grabber_sink_events_vtbl; object->refcount = 1; - object->callback = context->callback; - IMFSampleGrabberSinkCallback_AddRef(object->callback); + if (FAILED(IMFSampleGrabberSinkCallback_QueryInterface(context->callback, &IID_IMFSampleGrabberSinkCallback2, + (void **)&object->callback2))) + { + object->callback = context->callback; + IMFSampleGrabberSinkCallback_AddRef(object->callback); + } object->media_type = context->media_type; IMFMediaType_AddRef(object->media_type); IMFAttributes_GetUINT32(attributes, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, &object->ignore_clock); diff --git a/include/mfidl.idl b/include/mfidl.idl index 4968bf9aa70..66a84771a7c 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -549,6 +549,23 @@ interface IMFSampleGrabberSinkCallback : IMFClockStateSink HRESULT OnShutdown(); } +[ + object, + uuid(ca86aa50-c46e-429e-ab27-16d6ac6844cb), + local +] +interface IMFSampleGrabberSinkCallback2 : IMFSampleGrabberSinkCallback +{ + HRESULT OnProcessSampleEx( + [in] REFGUID major_type, + [in] DWORD sample_flags, + [in] LONGLONG sample_time, + [in] LONGLONG sample_duration, + [in] const BYTE *buffer, + [in] DWORD sample_size, + [in] IMFAttributes *attributes); +} + cpp_quote("HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **session);") cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream);" ) cpp_quote("HRESULT WINAPI MFCreateMFByteStreamOnStreamEx(IUnknown *stream, IMFByteStream **bytestream);")