Nikolay Sivov : mfreadwrite/reader: Subscribe to allocator's release notifications.

Alexandre Julliard julliard at winehq.org
Wed Feb 17 16:23:33 CST 2021


Module: wine
Branch: master
Commit: a0a6fad695d2f9d1eb2601725ac27c9a9949026b
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=a0a6fad695d2f9d1eb2601725ac27c9a9949026b

Author: Nikolay Sivov <nsivov at codeweavers.com>
Date:   Wed Feb 17 16:14:04 2021 +0300

mfreadwrite/reader: Subscribe to allocator's release notifications.

Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/mfreadwrite/reader.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 70 insertions(+)

diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c
index 6a69196054a..ec7d3fd62e6 100644
--- a/dlls/mfreadwrite/reader.c
+++ b/dlls/mfreadwrite/reader.c
@@ -112,12 +112,14 @@ struct media_stream
     IMFMediaType *current;
     IMFTransform *decoder;
     IMFVideoSampleAllocatorEx *allocator;
+    IMFVideoSampleAllocatorNotify notify_cb;
     unsigned int id;
     unsigned int index;
     enum media_stream_state state;
     unsigned int flags;
     unsigned int requests;
     unsigned int responses;
+    struct source_reader *reader;
 };
 
 enum source_reader_async_op
@@ -126,6 +128,7 @@ enum source_reader_async_op
     SOURCE_READER_ASYNC_SEEK,
     SOURCE_READER_ASYNC_FLUSH,
     SOURCE_READER_ASYNC_SAMPLE_READY,
+    SOURCE_READER_ASYNC_SA_READY,
 };
 
 struct source_reader_async_command
@@ -153,6 +156,10 @@ struct source_reader_async_command
         {
             unsigned int stream_index;
         } sample;
+        struct
+        {
+            unsigned int stream_index;
+        } sa;
     } u;
 };
 
@@ -216,6 +223,11 @@ static struct source_reader_async_command *impl_from_async_command_IUnknown(IUnk
     return CONTAINING_RECORD(iface, struct source_reader_async_command, IUnknown_iface);
 }
 
+static struct media_stream *impl_stream_from_IMFVideoSampleAllocatorNotify(IMFVideoSampleAllocatorNotify *iface)
+{
+    return CONTAINING_RECORD(iface, struct media_stream, notify_cb);
+}
+
 static HRESULT WINAPI source_reader_async_command_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
 {
     if (IsEqualIID(riid, &IID_IUnknown))
@@ -1533,6 +1545,7 @@ static HRESULT source_reader_setup_sample_allocator(struct source_reader *reader
         IMFMediaType *media_type)
 {
     struct media_stream *stream = &reader->streams[index];
+    IMFVideoSampleAllocatorCallback *callback;
     GUID major = { 0 };
     HRESULT hr;
 
@@ -1568,6 +1581,13 @@ static HRESULT source_reader_setup_sample_allocator(struct source_reader *reader
     if (FAILED(hr = IMFVideoSampleAllocatorEx_InitializeSampleAllocatorEx(stream->allocator, 2, 8, NULL, media_type)))
         WARN("Failed to initialize sample allocator, hr %#x.\n", hr);
 
+    if (SUCCEEDED(IMFVideoSampleAllocatorEx_QueryInterface(stream->allocator, &IID_IMFVideoSampleAllocatorCallback, (void **)&callback)))
+    {
+        if (FAILED(hr = IMFVideoSampleAllocatorCallback_SetCallback(callback, &stream->notify_cb)))
+            WARN("Failed to set allocator callback, hr %#x.\n", hr);
+        IMFVideoSampleAllocatorCallback_Release(callback);
+    }
+
     return hr;
 }
 
@@ -2126,6 +2146,54 @@ static DWORD reader_get_first_stream_index(IMFPresentationDescriptor *descriptor
     return MF_SOURCE_READER_INVALID_STREAM_INDEX;
 }
 
+static HRESULT WINAPI stream_sample_allocator_cb_QueryInterface(IMFVideoSampleAllocatorNotify *iface,
+        REFIID riid, void **obj)
+{
+    if (IsEqualIID(riid, &IID_IMFVideoSampleAllocatorNotify) ||
+            IsEqualIID(riid, &IID_IUnknown))
+    {
+        *obj = iface;
+        IMFVideoSampleAllocatorNotify_AddRef(iface);
+        return S_OK;
+    }
+
+    *obj = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI stream_sample_allocator_cb_AddRef(IMFVideoSampleAllocatorNotify *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI stream_sample_allocator_cb_Release(IMFVideoSampleAllocatorNotify *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI stream_sample_allocator_cb_NotifyRelease(IMFVideoSampleAllocatorNotify *iface)
+{
+    struct media_stream *stream = impl_stream_from_IMFVideoSampleAllocatorNotify(iface);
+    struct source_reader_async_command *command;
+
+    if (SUCCEEDED(source_reader_create_async_op(SOURCE_READER_ASYNC_SA_READY, &command)))
+    {
+        command->u.sa.stream_index = stream->index;
+        MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &stream->reader->async_commands_callback, &command->IUnknown_iface);
+        IUnknown_Release(&command->IUnknown_iface);
+    }
+
+    return S_OK;
+}
+
+static const IMFVideoSampleAllocatorNotifyVtbl stream_sample_allocator_cb_vtbl =
+{
+    stream_sample_allocator_cb_QueryInterface,
+    stream_sample_allocator_cb_AddRef,
+    stream_sample_allocator_cb_Release,
+    stream_sample_allocator_cb_NotifyRelease,
+};
+
 static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttributes *attributes,
         BOOL shutdown_on_release, REFIID riid, void **out)
 {
@@ -2195,6 +2263,8 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
         if (FAILED(hr))
             break;
 
+        object->streams[i].notify_cb.lpVtbl = &stream_sample_allocator_cb_vtbl;
+        object->streams[i].reader = object;
         object->streams[i].index = i;
     }
 




More information about the wine-cvs mailing list