Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 98 ++++++++++++++++++++++++--------------- 1 file changed, 61 insertions(+), 37 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 19885ef61e..74aa2dc557 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -131,6 +131,11 @@ struct source_reader_async_command unsigned int stream_index; };
+enum source_reader_flags +{ + SOURCE_READER_FLUSHING = 0x1, +}; + struct source_reader { IMFSourceReader IMFSourceReader_iface; @@ -144,6 +149,7 @@ struct source_reader DWORD first_video_stream_index; IMFSourceReaderCallback *async_callback; BOOL shutdown_on_release; + unsigned int flags; enum media_source_state source_state; struct media_stream *streams; DWORD stream_count; @@ -1000,38 +1006,23 @@ static void source_reader_release_responses(struct source_reader *reader, struct
static void source_reader_flush_stream(struct source_reader *reader, DWORD stream_index) { - struct media_stream *stream = stream_index == MF_SOURCE_READER_ALL_STREAMS ? NULL : &reader->streams[stream_index]; - unsigned int i; + struct media_stream *stream = &reader->streams[stream_index];
source_reader_release_responses(reader, stream); - if (stream) - { - if (stream->decoder) - IMFTransform_ProcessMessage(stream->decoder, MFT_MESSAGE_COMMAND_FLUSH, 0); - - stream->requests = 0; - } - else - { - for (i = 0; i < reader->stream_count; i++) - { - if (reader->streams[i].decoder) - IMFTransform_ProcessMessage(reader->streams[i].decoder, MFT_MESSAGE_COMMAND_FLUSH, 0); - - reader->streams[i].requests = 0; - } - } + if (stream->decoder) + IMFTransform_ProcessMessage(stream->decoder, MFT_MESSAGE_COMMAND_FLUSH, 0); + stream->requests = 0; }
static HRESULT source_reader_flush(struct source_reader *reader, unsigned int index) { unsigned int stream_index; - - EnterCriticalSection(&reader->cs); + HRESULT hr = S_OK;
if (index == MF_SOURCE_READER_ALL_STREAMS) { - source_reader_flush_stream(reader, index); + for (stream_index = 0; stream_index < reader->stream_count; ++stream_index) + source_reader_flush_stream(reader, stream_index); } else { @@ -1047,12 +1038,13 @@ static HRESULT source_reader_flush(struct source_reader *reader, unsigned int in stream_index = index; }
- source_reader_flush_stream(reader, stream_index); + if (stream_index < reader->stream_count) + source_reader_flush_stream(reader, stream_index); + else + hr = MF_E_INVALIDSTREAMNUMBER; }
- LeaveCriticalSection(&reader->cs); - - return S_OK; + return hr; }
static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) @@ -1125,7 +1117,10 @@ static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallb
break; case SOURCE_READER_ASYNC_FLUSH: + EnterCriticalSection(&reader->cs); source_reader_flush(reader, command->stream_index); + reader->flags &= ~SOURCE_READER_FLUSHING; + LeaveCriticalSection(&reader->cs);
IMFSourceReaderCallback_OnFlush(reader->async_callback, command->stream_index); break; @@ -1692,28 +1687,57 @@ static HRESULT WINAPI src_reader_ReadSample(IMFSourceReader *iface, DWORD index, return hr; }
+static HRESULT source_reader_flush_async(struct source_reader *reader, unsigned int index) +{ + struct source_reader_async_command *command; + unsigned int stream_index; + HRESULT hr; + + switch (index) + { + case MF_SOURCE_READER_FIRST_VIDEO_STREAM: + stream_index = reader->first_video_stream_index; + break; + case MF_SOURCE_READER_FIRST_AUDIO_STREAM: + stream_index = reader->first_audio_stream_index; + break; + default: + stream_index = index; + } + + reader->flags |= SOURCE_READER_FLUSHING; + + if (stream_index != MF_SOURCE_READER_ALL_STREAMS && stream_index >= reader->stream_count) + return MF_E_INVALIDSTREAMNUMBER; + + if (FAILED(hr = source_reader_create_async_op(SOURCE_READER_ASYNC_FLUSH, &command))) + return hr; + + command->stream_index = stream_index; + + hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &reader->async_commands_callback, + &command->IUnknown_iface); + IUnknown_Release(&command->IUnknown_iface); + + return hr; +} + static HRESULT WINAPI src_reader_Flush(IMFSourceReader *iface, DWORD index) { struct source_reader *reader = impl_from_IMFSourceReader(iface); - struct source_reader_async_command *command; HRESULT hr;
TRACE("%p, %#x.\n", iface, index);
- if (reader->async_callback) - { - if (FAILED(hr = source_reader_create_async_op(SOURCE_READER_ASYNC_FLUSH, &command))) - return hr; - - command->stream_index = index; + EnterCriticalSection(&reader->cs);
- hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &reader->async_commands_callback, - &command->IUnknown_iface); - IUnknown_Release(&command->IUnknown_iface); - } + if (reader->async_callback) + hr = source_reader_flush_async(reader, index); else hr = source_reader_flush(reader, index);
+ LeaveCriticalSection(&reader->cs); + return hr; }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 74aa2dc557..a8df4da763 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1715,8 +1715,7 @@ static HRESULT source_reader_flush_async(struct source_reader *reader, unsigned
command->stream_index = stream_index;
- hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_MULTITHREADED, &reader->async_commands_callback, - &command->IUnknown_iface); + hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &reader->async_commands_callback, &command->IUnknown_iface); IUnknown_Release(&command->IUnknown_iface);
return hr;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 45 +++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 14 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index a8df4da763..df921307e9 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1658,29 +1658,46 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind return hr; }
-static HRESULT WINAPI src_reader_ReadSample(IMFSourceReader *iface, DWORD index, DWORD flags, DWORD *actual_index, - DWORD *stream_flags, LONGLONG *timestamp, IMFSample **sample) +static HRESULT source_reader_read_sample_async(struct source_reader *reader, unsigned int index, unsigned int flags, + unsigned int *actual_index, unsigned int *stream_flags, LONGLONG *timestamp, IMFSample **sample) { - struct source_reader *reader = impl_from_IMFSourceReader(iface); struct source_reader_async_command *command; HRESULT hr;
- TRACE("%p, %#x, %#x, %p, %p, %p, %p\n", iface, index, flags, actual_index, stream_flags, timestamp, sample); + if (actual_index || stream_flags || timestamp || sample) + return E_INVALIDARG;
- if (reader->async_callback) + EnterCriticalSection(&reader->cs); + + if (reader->flags & SOURCE_READER_FLUSHING) + hr = MF_E_NOTACCEPTING; + else { - if (actual_index || stream_flags || timestamp || sample) - return E_INVALIDARG; + if (SUCCEEDED(hr = source_reader_create_async_op(SOURCE_READER_ASYNC_READ, &command))) + { + command->stream_index = index; + command->flags = flags;
- if (FAILED(hr = source_reader_create_async_op(SOURCE_READER_ASYNC_READ, &command))) - return hr; + hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &reader->async_commands_callback, &command->IUnknown_iface); + IUnknown_Release(&command->IUnknown_iface); + } + } + + LeaveCriticalSection(&reader->cs);
- command->stream_index = index; - command->flags = flags; + return hr; +}
- hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &reader->async_commands_callback, &command->IUnknown_iface); - IUnknown_Release(&command->IUnknown_iface); - } +static HRESULT WINAPI src_reader_ReadSample(IMFSourceReader *iface, DWORD index, DWORD flags, DWORD *actual_index, + DWORD *stream_flags, LONGLONG *timestamp, IMFSample **sample) +{ + struct source_reader *reader = impl_from_IMFSourceReader(iface); + HRESULT hr; + + TRACE("%p, %#x, %#x, %p, %p, %p, %p\n", iface, index, flags, actual_index, stream_flags, timestamp, sample); + + if (reader->async_callback) + hr = source_reader_read_sample_async(reader, index, flags, actual_index, stream_flags, timestamp, sample); else hr = source_reader_read_sample(reader, index, flags, actual_index, stream_flags, timestamp, sample);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index df921307e9..17d274ebc8 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -134,6 +134,7 @@ struct source_reader_async_command enum source_reader_flags { SOURCE_READER_FLUSHING = 0x1, + SOURCE_READER_SHUTDOWN_ON_RELEASE = 0x2, };
struct source_reader @@ -148,7 +149,6 @@ struct source_reader DWORD first_audio_stream_index; DWORD first_video_stream_index; IMFSourceReaderCallback *async_callback; - BOOL shutdown_on_release; unsigned int flags; enum media_source_state source_state; struct media_stream *streams; @@ -1186,7 +1186,7 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) { if (reader->async_callback) IMFSourceReaderCallback_Release(reader->async_callback); - if (reader->shutdown_on_release) + if (reader->flags & SOURCE_READER_SHUTDOWN_ON_RELEASE) IMFMediaSource_Shutdown(reader->source); if (reader->descriptor) IMFPresentationDescriptor_Release(reader->descriptor); @@ -1917,6 +1917,8 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri object->async_commands_callback.lpVtbl = &async_commands_callback_vtbl; object->refcount = 1; list_init(&object->responses); + if (shutdown_on_release) + object->flags |= SOURCE_READER_SHUTDOWN_ON_RELEASE; object->source = source; IMFMediaSource_AddRef(object->source); InitializeCriticalSection(&object->cs);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 3 +++ dlls/mfreadwrite/tests/mfplat.c | 7 +++++++ 2 files changed, 10 insertions(+)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 17d274ebc8..e46b6003eb 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1710,6 +1710,9 @@ static HRESULT source_reader_flush_async(struct source_reader *reader, unsigned unsigned int stream_index; HRESULT hr;
+ if (reader->flags & SOURCE_READER_FLUSHING) + return MF_E_INVALIDREQUEST; + switch (index) { case MF_SOURCE_READER_FIRST_VIDEO_STREAM: diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index e03d74981a..c35cfa3c0c 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -951,6 +951,13 @@ todo_wine hr = IMFSourceReader_ReadSample(reader, 0, 0, NULL, NULL, NULL, &sample); ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr);
+ /* Flush() arguments validation. */ + hr = IMFSourceReader_Flush(reader, 123); + ok(hr == MF_E_INVALIDSTREAMNUMBER, "Unexpected hr %#x.\n", hr); + + hr = IMFSourceReader_ReadSample(reader, 0, 0, NULL, NULL, NULL, NULL); + ok(hr == MF_E_NOTACCEPTING, "Unexpected hr %#x.\n", hr); + IMFSourceReader_Release(reader); }