[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