mfreadwrite: Handle MEMediaSample event.

Signed-off-by: Nikolay Sivov <nsivov@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Nikolay Sivov 2019-04-19 11:06:14 +03:00 committed by Alexandre Julliard
parent 002010e31a
commit fcf8cbfb2a
1 changed files with 95 additions and 4 deletions

View File

@ -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))