[PATCH 4/5] mfreadwrite: Handle MEMediaSample event.

Nikolay Sivov nsivov at codeweavers.com
Fri Apr 19 03:06:14 CDT 2019


Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 dlls/mfreadwrite/main.c | 99 +++++++++++++++++++++++++++++++++++++++--
 1 file changed, 95 insertions(+), 4 deletions(-)

diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c
index 84db9aa600..43dfd4e9ed 100644
--- a/dlls/mfreadwrite/main.c
+++ b/dlls/mfreadwrite/main.c
@@ -37,6 +37,7 @@
 
 #include "wine/debug.h"
 #include "wine/heap.h"
+#include "wine/list.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
 
@@ -72,11 +73,19 @@ HRESULT WINAPI DllUnregisterServer(void)
     return __wine_unregister_resources( mfinstance );
 }
 
+struct sample
+{
+    struct list entry;
+    IMFSample *sample;
+};
+
 struct media_stream
 {
     IMFMediaStream *stream;
     IMFMediaType *current;
     DWORD id;
+    CRITICAL_SECTION cs;
+    struct list samples;
 };
 
 typedef struct source_reader
@@ -308,8 +317,64 @@ static ULONG WINAPI source_reader_stream_events_callback_Release(IMFAsyncCallbac
     return IMFSourceReader_Release(&reader->IMFSourceReader_iface);
 }
 
+static HRESULT source_reader_media_sample_handler(struct source_reader *reader, IMFMediaStream *stream,
+        IMFMediaEvent *event)
+{
+    IMFSample *sample;
+    unsigned int i;
+    DWORD id = 0;
+    HRESULT hr;
+
+    TRACE("Got new sample for stream %p.\n", stream);
+
+    if (FAILED(hr = media_event_get_object(event, &IID_IMFSample, (void **)&sample)))
+    {
+        WARN("Failed to get sample object, hr %#x.\n", hr);
+        return hr;
+    }
+
+    if (FAILED(hr = media_stream_get_id(stream, &id)))
+    {
+        WARN("Unidentified stream %p, hr %#x.\n", stream, hr);
+        IMFSample_Release(sample);
+        return hr;
+    }
+
+    for (i = 0; i < reader->stream_count; ++i)
+    {
+        if (id == reader->streams[i].id)
+        {
+            struct sample *pending_sample;
+
+            if (!(pending_sample = heap_alloc(sizeof(*pending_sample))))
+            {
+                hr = E_OUTOFMEMORY;
+                goto failed;
+            }
+
+            pending_sample->sample = sample;
+            IMFSample_AddRef(pending_sample->sample);
+
+            EnterCriticalSection(&reader->streams[i].cs);
+            list_add_tail(&reader->streams[i].samples, &pending_sample->entry);
+            LeaveCriticalSection(&reader->streams[i].cs);
+
+            break;
+        }
+    }
+
+    if (i == reader->stream_count)
+        WARN("Stream with id %#x was not present in presentation descriptor.\n", id);
+
+failed:
+    IMFSample_Release(sample);
+
+    return hr;
+}
+
 static HRESULT WINAPI source_reader_stream_events_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result)
 {
+    struct source_reader *reader = impl_from_stream_callback_IMFAsyncCallback(iface);
     MediaEventType event_type;
     IMFMediaStream *stream;
     IMFMediaEvent *event;
@@ -326,6 +391,18 @@ static HRESULT WINAPI source_reader_stream_events_callback_Invoke(IMFAsyncCallba
 
     TRACE("Got event %u.\n", event_type);
 
+    switch (event_type)
+    {
+        case MEMediaSample:
+            hr = source_reader_media_sample_handler(reader, stream, event);
+            break;
+        default:
+            ;
+    }
+
+    if (FAILED(hr))
+        WARN("Failed while handling %d event, hr %#x.\n", event_type, hr);
+
     IMFMediaEvent_Release(event);
 
     IMFMediaStream_BeginGetEvent(stream, iface, (IUnknown *)stream);
@@ -394,10 +471,21 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface)
 
         for (i = 0; i < reader->stream_count; ++i)
         {
-            if (reader->streams[i].stream)
-                IMFMediaStream_Release(reader->streams[i].stream);
-            if (reader->streams[i].current)
-                IMFMediaType_Release(reader->streams[i].current);
+            struct media_stream *stream = &reader->streams[i];
+            struct sample *ptr, *next;
+
+            if (stream->stream)
+                IMFMediaStream_Release(stream->stream);
+            if (stream->current)
+                IMFMediaType_Release(stream->current);
+            DeleteCriticalSection(&stream->cs);
+
+            LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &stream->samples, struct sample, entry)
+            {
+                IMFSample_Release(ptr->sample);
+                list_remove(&ptr->entry);
+                heap_free(ptr);
+            }
         }
         heap_free(reader->streams);
         DeleteCriticalSection(&reader->cs);
@@ -832,6 +920,9 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
         IMFMediaType_Release(src_type);
         if (FAILED(hr))
             break;
+
+        InitializeCriticalSection(&object->streams[i].cs);
+        list_init(&object->streams[i].samples);
     }
 
     if (FAILED(hr))
-- 
2.20.1




More information about the wine-devel mailing list