Nikolay Sivov : mfreadwrite: Make pending response reader structure more generic.
Alexandre Julliard
julliard at winehq.org
Wed Mar 25 17:07:27 CDT 2020
Module: wine
Branch: master
Commit: 66de5a8ee8e6c6c78a9b2bfff1d5c33e5889d555
URL: https://source.winehq.org/git/wine.git/?a=commit;h=66de5a8ee8e6c6c78a9b2bfff1d5c33e5889d555
Author: Nikolay Sivov <nsivov at codeweavers.com>
Date: Wed Mar 25 14:39:57 2020 +0300
mfreadwrite: Make pending response reader structure more generic.
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/mfreadwrite/main.c | 104 +++++++++++++++++++++++++++++-------------------
1 file changed, 63 insertions(+), 41 deletions(-)
diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c
index 8c994273cb..3faa6c6ee0 100644
--- a/dlls/mfreadwrite/main.c
+++ b/dlls/mfreadwrite/main.c
@@ -72,9 +72,13 @@ HRESULT WINAPI DllUnregisterServer(void)
return __wine_unregister_resources( mfinstance );
}
-struct sample
+struct stream_response
{
struct list entry;
+ HRESULT status;
+ DWORD stream_index;
+ DWORD stream_flags;
+ LONGLONG timestamp;
IMFSample *sample;
};
@@ -96,9 +100,10 @@ struct media_stream
IMFMediaType *current;
IMFTransform *decoder;
DWORD id;
+ unsigned int index;
CRITICAL_SECTION cs;
CONDITION_VARIABLE sample_event;
- struct list samples;
+ struct list responses;
enum media_stream_state state;
BOOL selected;
BOOL presented;
@@ -366,18 +371,21 @@ static ULONG WINAPI source_reader_stream_events_callback_Release(IMFAsyncCallbac
return IMFSourceReader_Release(&reader->IMFSourceReader_iface);
}
-static void source_reader_queue_sample(struct media_stream *stream, IMFSample *sample)
+static void source_reader_queue_response(struct media_stream *stream, HRESULT status, DWORD stream_index,
+ DWORD stream_flags, LONGLONG timestamp, IMFSample *sample)
{
- struct sample *pending_sample;
-
- if (!sample)
- return;
+ struct stream_response *response;
- pending_sample = heap_alloc(sizeof(*pending_sample));
- pending_sample->sample = sample;
- IMFSample_AddRef(pending_sample->sample);
+ response = heap_alloc_zero(sizeof(*response));
+ response->status = status;
+ response->stream_index = stream_index;
+ response->stream_flags = stream_flags;
+ response->timestamp = timestamp;
+ response->sample = sample;
+ if (response->sample)
+ IMFSample_AddRef(response->sample);
- list_add_tail(&stream->samples, &pending_sample->entry);
+ list_add_tail(&stream->responses, &response->entry);
}
static HRESULT source_reader_pull_stream_samples(struct media_stream *stream)
@@ -385,6 +393,7 @@ static HRESULT source_reader_pull_stream_samples(struct media_stream *stream)
MFT_OUTPUT_STREAM_INFO stream_info = { 0 };
MFT_OUTPUT_DATA_BUFFER out_buffer;
IMFMediaBuffer *buffer;
+ LONGLONG timestamp;
DWORD status;
HRESULT hr;
@@ -420,7 +429,11 @@ static HRESULT source_reader_pull_stream_samples(struct media_stream *stream)
break;
}
- source_reader_queue_sample(stream, out_buffer.pSample);
+ timestamp = 0;
+ if (FAILED(IMFSample_GetSampleTime(out_buffer.pSample, ×tamp)))
+ WARN("Sample time wasn't set.\n");
+
+ source_reader_queue_response(stream, S_OK /* FIXME */, stream->index, 0, timestamp, out_buffer.pSample);
if (out_buffer.pSample)
IMFSample_Release(out_buffer.pSample);
if (out_buffer.pEvents)
@@ -432,11 +445,16 @@ static HRESULT source_reader_pull_stream_samples(struct media_stream *stream)
static HRESULT source_reader_process_sample(struct media_stream *stream, IMFSample *sample)
{
+ LONGLONG timestamp;
HRESULT hr;
if (!stream->decoder)
{
- source_reader_queue_sample(stream, sample);
+ timestamp = 0;
+ if (FAILED(IMFSample_GetSampleTime(sample, ×tamp)))
+ WARN("Sample time wasn't set.\n");
+
+ source_reader_queue_response(stream, S_OK, stream->index, 0, timestamp, sample);
return S_OK;
}
@@ -667,7 +685,7 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface)
for (i = 0; i < reader->stream_count; ++i)
{
struct media_stream *stream = &reader->streams[i];
- struct sample *ptr, *next;
+ struct stream_response *ptr, *next;
if (stream->stream)
IMFMediaStream_Release(stream->stream);
@@ -677,9 +695,10 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface)
IMFTransform_Release(stream->decoder);
DeleteCriticalSection(&stream->cs);
- LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &stream->samples, struct sample, entry)
+ LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &stream->responses, struct stream_response, entry)
{
- IMFSample_Release(ptr->sample);
+ if (ptr->sample)
+ IMFSample_Release(ptr->sample);
list_remove(&ptr->entry);
heap_free(ptr);
}
@@ -1089,22 +1108,18 @@ static HRESULT WINAPI src_reader_SetCurrentPosition(IMFSourceReader *iface, REFG
return IMFMediaSource_Start(reader->source, reader->descriptor, format, position);
}
-static IMFSample *media_stream_pop_sample(struct media_stream *stream, DWORD *stream_flags)
+static struct stream_response *media_stream_pop_response(struct media_stream *stream)
{
- IMFSample *ret = NULL;
+ struct stream_response *response = NULL;
struct list *head;
- if ((head = list_head(&stream->samples)))
+ if ((head = list_head(&stream->responses)))
{
- struct sample *pending_sample = LIST_ENTRY(head, struct sample, entry);
- ret = pending_sample->sample;
- list_remove(&pending_sample->entry);
- heap_free(pending_sample);
+ response = LIST_ENTRY(head, struct stream_response, entry);
+ list_remove(&response->entry);
}
- *stream_flags = (!ret && stream->state == STREAM_STATE_EOS) ? MF_SOURCE_READERF_ENDOFSTREAM : 0;
-
- return ret;
+ return response;
}
static HRESULT source_reader_start_source(struct source_reader *reader)
@@ -1145,6 +1160,7 @@ static HRESULT source_reader_start_source(struct source_reader *reader)
static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD index, DWORD flags, DWORD *actual_index,
DWORD *stream_flags, LONGLONG *timestamp, IMFSample **sample)
{
+ struct stream_response *response;
struct media_stream *stream;
DWORD stream_index;
HRESULT hr = S_OK;
@@ -1155,6 +1171,9 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind
*sample = NULL;
+ if (timestamp)
+ *timestamp = 0;
+
switch (index)
{
case MF_SOURCE_READER_FIRST_VIDEO_STREAM:
@@ -1179,8 +1198,6 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind
*stream_flags = MF_SOURCE_READERF_ERROR;
if (actual_index)
*actual_index = index;
- if (timestamp)
- *timestamp = 0;
return hr;
}
@@ -1195,7 +1212,7 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind
{
if (!(flags & MF_SOURCE_READER_CONTROLF_DRAIN))
{
- while (list_empty(&stream->samples) && stream->state != STREAM_STATE_EOS)
+ while (list_empty(&stream->responses) && stream->state != STREAM_STATE_EOS)
{
if (stream->stream)
{
@@ -1206,21 +1223,25 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind
}
}
- *sample = media_stream_pop_sample(stream, stream_flags);
+ if ((response = media_stream_pop_response(stream)))
+ {
+ *stream_flags = response->stream_flags;
+ if (timestamp)
+ *timestamp = response->timestamp;
+ *sample = response->sample;
+ if (*sample)
+ IMFSample_AddRef(*sample);
+ }
+ else
+ {
+ *stream_flags = list_empty(&stream->responses) && stream->state == STREAM_STATE_EOS ?
+ MF_SOURCE_READERF_ENDOFSTREAM : 0;
+ }
}
LeaveCriticalSection(&stream->cs);
- TRACE("Got sample %p.\n", *sample);
-
- if (timestamp)
- {
- /* TODO: it's possible timestamp has to be set for some events.
- For MEEndOfStream it's correct to return 0. */
- *timestamp = 0;
- if (*sample)
- IMFSample_GetSampleTime(*sample, timestamp);
- }
+ TRACE("Got sample %p, flags %#x.\n", *sample, *stream_flags);
return hr;
}
@@ -1466,9 +1487,10 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri
if (FAILED(hr))
break;
+ object->streams[i].index = i;
InitializeCriticalSection(&object->streams[i].cs);
InitializeConditionVariable(&object->streams[i].sample_event);
- list_init(&object->streams[i].samples);
+ list_init(&object->streams[i].responses);
}
if (FAILED(hr))
More information about the wine-cvs
mailing list