Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 228 ++++++++++++++++++++++---------------- 1 file changed, 130 insertions(+), 98 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 9a7c5e5fd7..b8e1ab0106 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -108,9 +108,6 @@ struct media_stream IMFTransform *decoder; DWORD id; unsigned int index; - CRITICAL_SECTION cs; - CONDITION_VARIABLE sample_event; - struct list responses; enum media_stream_state state; BOOL selected; BOOL presented; @@ -150,7 +147,9 @@ struct source_reader enum media_source_state source_state; struct media_stream *streams; DWORD stream_count; + struct list responses; CRITICAL_SECTION cs; + CONDITION_VARIABLE sample_event; };
static inline struct source_reader *impl_from_IMFSourceReader(IMFSourceReader *iface) @@ -327,7 +326,7 @@ static void source_reader_queue_response(struct source_reader *reader, struct me if (response->sample) IMFSample_AddRef(response->sample);
- list_add_tail(&stream->responses, &response->entry); + list_add_tail(&reader->responses, &response->entry);
if (stream->requests) { @@ -343,7 +342,7 @@ static void source_reader_queue_response(struct source_reader *reader, struct me } } else - WakeAllConditionVariable(&stream->sample_event); + WakeAllConditionVariable(&reader->sample_event);
stream->requests--; } @@ -386,12 +385,15 @@ static HRESULT source_reader_new_stream_handler(struct source_reader *reader, IM return hr; }
+ EnterCriticalSection(&reader->cs); + for (i = 0; i < reader->stream_count; ++i) { if (id == reader->streams[i].id) { - if (!InterlockedCompareExchangePointer((void **)&reader->streams[i].stream, stream, NULL)) + if (!reader->streams[i].stream) { + reader->streams[i].stream = stream; IMFMediaStream_AddRef(reader->streams[i].stream); if (FAILED(hr = IMFMediaStream_BeginGetEvent(stream, &reader->stream_events_callback, (IUnknown *)stream))) @@ -399,10 +401,8 @@ static HRESULT source_reader_new_stream_handler(struct source_reader *reader, IM WARN("Failed to subscribe to stream events, hr %#x.\n", hr); }
- EnterCriticalSection(&reader->streams[i].cs); if (reader->streams[i].requests) source_reader_request_sample(reader, &reader->streams[i]); - LeaveCriticalSection(&reader->streams[i].cs); } break; } @@ -411,6 +411,8 @@ static HRESULT source_reader_new_stream_handler(struct source_reader *reader, IM if (i == reader->stream_count) WARN("Stream with id %#x was not present in presentation descriptor.\n", id);
+ LeaveCriticalSection(&reader->cs); + IMFMediaStream_Release(stream);
return hr; @@ -630,21 +632,19 @@ static HRESULT source_reader_media_sample_handler(struct source_reader *reader, return hr; }
+ EnterCriticalSection(&reader->cs); + for (i = 0; i < reader->stream_count; ++i) { if (id == reader->streams[i].id) { /* FIXME: propagate processing errors? */
- EnterCriticalSection(&reader->streams[i].cs); - reader->streams[i].flags &= ~STREAM_FLAG_SAMPLE_REQUESTED; hr = source_reader_process_sample(reader, &reader->streams[i], sample); if (reader->streams[i].requests) source_reader_request_sample(reader, &reader->streams[i]);
- LeaveCriticalSection(&reader->streams[i].cs); - break; } } @@ -652,6 +652,8 @@ static HRESULT source_reader_media_sample_handler(struct source_reader *reader, if (i == reader->stream_count) WARN("Stream with id %#x was not present in presentation descriptor.\n", id);
+ LeaveCriticalSection(&reader->cs); + IMFSample_Release(sample);
return hr; @@ -675,14 +677,14 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re return hr; }
+ EnterCriticalSection(&reader->cs); + for (i = 0; i < reader->stream_count; ++i) { struct media_stream *stream = &reader->streams[i];
if (id == stream->id) { - EnterCriticalSection(&stream->cs); - switch (event_type) { case MEEndOfStream: @@ -716,12 +718,12 @@ static HRESULT source_reader_media_stream_state_handler(struct source_reader *re ; }
- LeaveCriticalSection(&stream->cs); - break; } }
+ LeaveCriticalSection(&reader->cs); + return S_OK; }
@@ -790,18 +792,33 @@ static ULONG WINAPI source_reader_async_commands_callback_Release(IMFAsyncCallba return IMFSourceReader_Release(&reader->IMFSourceReader_iface); }
-static struct stream_response *media_stream_pop_response(struct media_stream *stream) +static struct stream_response *media_stream_pop_response(struct source_reader *reader, struct media_stream *stream) { - struct stream_response *response = NULL; + struct stream_response *response; struct list *head;
- if ((head = list_head(&stream->responses))) + if (stream) { - response = LIST_ENTRY(head, struct stream_response, entry); - list_remove(&response->entry); + LIST_FOR_EACH_ENTRY(response, &reader->responses, struct stream_response, entry) + { + if (response->stream_index == stream->index) + { + list_remove(&response->entry); + return response; + } + } + } + else + { + if ((head = list_head(&reader->responses))) + { + response = LIST_ENTRY(head, struct stream_response, entry); + list_remove(&response->entry); + return response; + } }
- return response; + return NULL; }
static void source_reader_release_response(struct stream_response *response) @@ -857,13 +874,38 @@ static HRESULT source_reader_start_source(struct source_reader *reader) return hr; }
+static BOOL source_reader_got_response_for_stream(struct source_reader *reader, struct media_stream *stream) +{ + struct stream_response *response; + + LIST_FOR_EACH_ENTRY(response, &reader->responses, struct stream_response, entry) + { + if (response->stream_index == stream->index) + return TRUE; + } + + return FALSE; +} + static BOOL source_reader_get_read_result(struct source_reader *reader, struct media_stream *stream, DWORD flags, HRESULT *status, DWORD *stream_index, DWORD *stream_flags, LONGLONG *timestamp, IMFSample **sample) { struct stream_response *response = NULL; BOOL request_sample = FALSE;
- if (list_empty(&stream->responses)) + if ((response = media_stream_pop_response(reader, stream))) + { + *status = response->status; + *stream_index = stream->index; + *stream_flags = response->stream_flags; + *timestamp = response->timestamp; + *sample = response->sample; + if (*sample) + IMFSample_AddRef(*sample); + + source_reader_release_response(response); + } + else { *status = S_OK; *stream_index = stream->index; @@ -880,20 +922,6 @@ static BOOL source_reader_get_read_result(struct source_reader *reader, struct m *stream_flags = 0; } } - else - { - response = media_stream_pop_response(stream); - - *status = response->status; - *stream_index = stream->index; - *stream_flags = response->stream_flags; - *timestamp = response->timestamp; - *sample = response->sample; - if (*sample) - IMFSample_AddRef(*sample); - - source_reader_release_response(response); - }
return !request_sample; } @@ -925,12 +953,19 @@ static HRESULT source_reader_get_stream_read_index(struct source_reader *reader, return hr; }
-static void source_reader_release_responses(struct media_stream *stream) +static void source_reader_release_responses(struct source_reader *reader, struct media_stream *stream) { struct stream_response *ptr, *next;
- LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &stream->responses, struct stream_response, entry) + LIST_FOR_EACH_ENTRY_SAFE(ptr, next, &reader->responses, struct stream_response, entry) { + if (stream && stream->index != ptr->stream_index && + ptr->stream_index != MF_SOURCE_READER_FIRST_VIDEO_STREAM && + ptr->stream_index != MF_SOURCE_READER_FIRST_AUDIO_STREAM && + ptr->stream_index != MF_SOURCE_READER_ANY_STREAM) + { + continue; + } list_remove(&ptr->entry); source_reader_release_response(ptr); } @@ -938,42 +973,42 @@ static void source_reader_release_responses(struct media_stream *stream)
static void source_reader_flush_stream(struct source_reader *reader, DWORD stream_index) { - struct media_stream *stream = &reader->streams[stream_index]; - - EnterCriticalSection(&stream->cs); + struct media_stream *stream = stream_index == MF_SOURCE_READER_ALL_STREAMS ? NULL : &reader->streams[stream_index];
- source_reader_release_responses(stream); + source_reader_release_responses(reader, stream); if (stream->decoder) IMFTransform_ProcessMessage(stream->decoder, MFT_MESSAGE_COMMAND_FLUSH, 0); stream->requests = 0; - - LeaveCriticalSection(&stream->cs); }
static HRESULT source_reader_flush(struct source_reader *reader, unsigned int index) { unsigned int stream_index;
- switch (index) + EnterCriticalSection(&reader->cs); + + if (index == MF_SOURCE_READER_ALL_STREAMS) { - 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; - case MF_SOURCE_READER_ALL_STREAMS: - for (stream_index = 0; stream_index < reader->stream_count; ++stream_index) - { - source_reader_flush_stream(reader, stream_index); - } + source_reader_flush_stream(reader, index); + } + else + { + 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; + }
- break; - default: - stream_index = index; + source_reader_flush_stream(reader, stream_index); }
- source_reader_flush_stream(reader, stream_index); + LeaveCriticalSection(&reader->cs);
return S_OK; } @@ -1002,9 +1037,9 @@ static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallb if (FAILED(hr = source_reader_get_stream_read_index(reader, command->stream_index, &stream_index))) return hr;
- stream = &reader->streams[stream_index]; + EnterCriticalSection(&reader->cs);
- EnterCriticalSection(&stream->cs); + stream = &reader->streams[stream_index];
if (SUCCEEDED(hr = source_reader_start_source(reader))) { @@ -1017,7 +1052,7 @@ static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallb } }
- LeaveCriticalSection(&stream->cs); + LeaveCriticalSection(&reader->cs);
if (report_sample) IMFSourceReaderCallback_OnReadSample(reader->async_callback, status, stream_index, stream_flags, @@ -1029,11 +1064,10 @@ static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallb break;
case SOURCE_READER_ASYNC_SAMPLE_READY: - stream = &reader->streams[command->stream_index];
- EnterCriticalSection(&stream->cs); - response = media_stream_pop_response(stream); - LeaveCriticalSection(&stream->cs); + EnterCriticalSection(&reader->cs); + response = media_stream_pop_response(reader, NULL); + LeaveCriticalSection(&reader->cs);
if (response) { @@ -1126,10 +1160,8 @@ static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) IMFMediaType_Release(stream->current); if (stream->decoder) IMFTransform_Release(stream->decoder); - DeleteCriticalSection(&stream->cs); - - source_reader_release_responses(stream); } + source_reader_release_responses(reader, NULL); heap_free(reader->streams); DeleteCriticalSection(&reader->cs); heap_free(reader); @@ -1544,39 +1576,40 @@ static HRESULT source_reader_read_sample(struct source_reader *reader, DWORD ind if (!actual_index) actual_index = &actual_index_tmp;
- if (FAILED(hr = source_reader_get_stream_read_index(reader, index, &stream_index))) - { - *actual_index = index; - *stream_flags = MF_SOURCE_READERF_ERROR; - *timestamp = 0; - return hr; - } - - *actual_index = stream_index; - - stream = &reader->streams[stream_index]; - - EnterCriticalSection(&stream->cs); + EnterCriticalSection(&reader->cs);
if (SUCCEEDED(hr = source_reader_start_source(reader))) { - if (!source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags, - timestamp, sample)) + if (SUCCEEDED(hr = source_reader_get_stream_read_index(reader, index, &stream_index))) { - while (list_empty(&stream->responses) && stream->state != STREAM_STATE_EOS) + *actual_index = stream_index; + + stream = &reader->streams[stream_index]; + + if (!source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags, + timestamp, sample)) { - stream->requests++; - if (FAILED(hr = source_reader_request_sample(reader, stream))) - WARN("Failed to request a sample, hr %#x.\n", hr); - SleepConditionVariableCS(&stream->sample_event, &stream->cs, INFINITE); - } + while (!source_reader_got_response_for_stream(reader, stream) && stream->state != STREAM_STATE_EOS) + { + stream->requests++; + if (FAILED(hr = source_reader_request_sample(reader, stream))) + WARN("Failed to request a sample, hr %#x.\n", hr); + SleepConditionVariableCS(&reader->sample_event, &reader->cs, INFINITE); + }
- source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags, - timestamp, sample); + source_reader_get_read_result(reader, stream, flags, &hr, actual_index, stream_flags, + timestamp, sample); + } + } + else + { + *actual_index = index; + *stream_flags = MF_SOURCE_READERF_ERROR; + *timestamp = 0; } }
- LeaveCriticalSection(&stream->cs); + LeaveCriticalSection(&reader->cs);
TRACE("Stream %u, got sample %p, flags %#x.\n", *actual_index, *sample, *stream_flags);
@@ -1796,9 +1829,11 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri object->stream_events_callback.lpVtbl = &stream_events_callback_vtbl; object->async_commands_callback.lpVtbl = &async_commands_callback_vtbl; object->refcount = 1; + list_init(&object->responses); object->source = source; IMFMediaSource_AddRef(object->source); InitializeCriticalSection(&object->cs); + InitializeConditionVariable(&object->sample_event);
if (FAILED(hr = IMFMediaSource_CreatePresentationDescriptor(object->source, &object->descriptor))) goto failed; @@ -1845,9 +1880,6 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri break;
object->streams[i].index = i; - InitializeCriticalSection(&object->streams[i].cs); - InitializeConditionVariable(&object->streams[i].sample_event); - list_init(&object->streams[i].responses); }
if (FAILED(hr))
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 52 ++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 14 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index b8e1ab0106..2fca4c2e1e 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -926,8 +926,9 @@ static BOOL source_reader_get_read_result(struct source_reader *reader, struct m return !request_sample; }
-static HRESULT source_reader_get_stream_read_index(struct source_reader *reader, DWORD index, DWORD *stream_index) +static HRESULT source_reader_get_stream_read_index(struct source_reader *reader, unsigned int index, unsigned int *stream_index) { + unsigned int i; BOOL selected; HRESULT hr;
@@ -940,8 +941,26 @@ static HRESULT source_reader_get_stream_read_index(struct source_reader *reader, *stream_index = reader->first_audio_stream_index; break; case MF_SOURCE_READER_ANY_STREAM: - FIXME("Non-specific requests are not supported.\n"); - return E_NOTIMPL; + if (reader->async_callback) + { + /* Pick first selected stream. */ + for (i = 0; i < reader->stream_count; ++i) + { + if (SUCCEEDED(source_reader_get_stream_selection(reader, i, &selected)) && selected) + { + *stream_index = i; + break; + } + } + + if (i == reader->stream_count) + return MF_E_MEDIA_SOURCE_NO_STREAMS_SELECTED; + } + else + { + FIXME("Non-specific requests are not supported.\n"); + return E_NOTIMPL; + } default: *stream_index = index; } @@ -1016,10 +1035,10 @@ static HRESULT source_reader_flush(struct source_reader *reader, unsigned int in static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { struct source_reader *reader = impl_from_async_commands_callback_IMFAsyncCallback(iface); + struct media_stream *stream, stub_stream = { .requests = 1 }; struct source_reader_async_command *command; struct stream_response *response; DWORD stream_index, stream_flags; - struct media_stream *stream; BOOL report_sample = FALSE; IMFSample *sample = NULL; LONGLONG timestamp = 0; @@ -1034,21 +1053,26 @@ static HRESULT WINAPI source_reader_async_commands_callback_Invoke(IMFAsyncCallb switch (command->op) { case SOURCE_READER_ASYNC_READ: - if (FAILED(hr = source_reader_get_stream_read_index(reader, command->stream_index, &stream_index))) - return hr; - EnterCriticalSection(&reader->cs);
- stream = &reader->streams[stream_index]; - if (SUCCEEDED(hr = source_reader_start_source(reader))) { - if (!(report_sample = source_reader_get_read_result(reader, stream, command->flags, &status, &stream_index, - &stream_flags, ×tamp, &sample))) + if (SUCCEEDED(hr = source_reader_get_stream_read_index(reader, command->stream_index, &stream_index))) { - stream->requests++; - source_reader_request_sample(reader, stream); - /* FIXME: set error stream/reader state on request failure */ + stream = &reader->streams[stream_index]; + + if (!(report_sample = source_reader_get_read_result(reader, stream, command->flags, &status, &stream_index, + &stream_flags, ×tamp, &sample))) + { + stream->requests++; + source_reader_request_sample(reader, stream); + /* FIXME: set error stream/reader state on request failure */ + } + } + else + { + stub_stream.index = command->stream_index; + source_reader_queue_response(reader, &stub_stream, hr, MF_SOURCE_READERF_ERROR, 0, NULL); } }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/reader.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 2fca4c2e1e..e14538c313 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -99,6 +99,8 @@ enum media_source_state enum media_stream_flags { STREAM_FLAG_SAMPLE_REQUESTED = 0x1, + STREAM_FLAG_SELECTED = 0x2, + STREAM_FLAG_PRESENTED = 0x4, };
struct media_stream @@ -109,9 +111,7 @@ struct media_stream DWORD id; unsigned int index; enum media_stream_state state; - BOOL selected; - BOOL presented; - DWORD flags; + unsigned int flags; unsigned int requests; };
@@ -841,18 +841,23 @@ static HRESULT source_reader_get_stream_selection(const struct source_reader *re
static HRESULT source_reader_start_source(struct source_reader *reader) { - BOOL selection_changed = FALSE; + BOOL selected, selection_changed = FALSE; PROPVARIANT position; HRESULT hr = S_OK; - DWORD i; + unsigned int i;
if (reader->source_state == SOURCE_STATE_STARTED) { for (i = 0; i < reader->stream_count; ++i) { - if (FAILED(hr = source_reader_get_stream_selection(reader, i, &reader->streams[i].selected))) + if (FAILED(hr = source_reader_get_stream_selection(reader, i, &selected))) return hr; - selection_changed = reader->streams[i].selected ^ reader->streams[i].presented; + if (selected) + reader->streams[i].flags |= STREAM_FLAG_SELECTED; + else + reader->streams[i].flags &= ~STREAM_FLAG_SELECTED; + selection_changed = !!(reader->streams[i].flags & STREAM_FLAG_SELECTED) ^ + !!(reader->streams[i].flags & STREAM_FLAG_PRESENTED); if (selection_changed) break; } @@ -867,7 +872,10 @@ static HRESULT source_reader_start_source(struct source_reader *reader) if (SUCCEEDED(hr = IMFMediaSource_Start(reader->source, reader->descriptor, &GUID_NULL, &position))) { for (i = 0; i < reader->stream_count; ++i) - reader->streams[i].presented = reader->streams[i].selected; + { + if (reader->streams[i].flags & STREAM_FLAG_SELECTED) + reader->streams[i].flags |= STREAM_FLAG_PRESENTED; + } } }
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mfplat.spec | 2 ++ dlls/rtworkq/queue.c | 14 ++++++++++++++ dlls/rtworkq/rtworkq.spec | 4 ++-- include/rtworkq.idl | 2 ++ 4 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 31d3777e87..5311757d2b 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -124,6 +124,7 @@ @ stub MFInitVideoFormat_RGB @ stdcall MFInvokeCallback(ptr) @ stub MFJoinIoPort +@ stdcall MFJoinWorkQueue(long long ptr) rtworkq.RtwqJoinWorkQueue @ stdcall MFLockPlatform() rtworkq.RtwqLockPlatform @ stdcall MFLockWorkQueue(long) rtworkq.RtwqLockWorkQueue @ stdcall MFPutWaitingWorkItem(long long ptr ptr) rtworkq.RtwqPutWaitingWorkItem @@ -158,6 +159,7 @@ @ stub MFTraceError @ stub MFTraceFuncEnter @ stub MFUnblockThread +@ stdcall MFUnjoinWorkQueue(long long) rtworkq.RtwqUnjoinWorkQueue @ stdcall MFUnlockPlatform() rtworkq.RtwqUnlockPlatform @ stdcall MFUnlockWorkQueue(long) rtworkq.RtwqUnlockWorkQueue @ stdcall MFUnwrapMediaType(ptr ptr) diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c index 85e84d46d6..32bd75b346 100644 --- a/dlls/rtworkq/queue.c +++ b/dlls/rtworkq/queue.c @@ -1471,3 +1471,17 @@ HRESULT WINAPI RtwqAllocateSerialWorkQueue(DWORD target_queue, DWORD *queue) desc.target_queue = target_queue; return alloc_user_queue(&desc, queue); } + +HRESULT WINAPI RtwqJoinWorkQueue(DWORD queue, HANDLE hFile, HANDLE *cookie) +{ + FIXME("%#x, %p, %p.\n", queue, hFile, cookie); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqUnjoinWorkQueue(DWORD queue, HANDLE cookie) +{ + FIXME("%#x, %p.\n", queue, cookie); + + return E_NOTIMPL; +} diff --git a/dlls/rtworkq/rtworkq.spec b/dlls/rtworkq/rtworkq.spec index adc05d679d..11955ac1a6 100644 --- a/dlls/rtworkq/rtworkq.spec +++ b/dlls/rtworkq/rtworkq.spec @@ -14,7 +14,7 @@ @ stub RtwqGetWorkQueueMMCSSPriority @ stub RtwqGetWorkQueueMMCSSTaskId @ stdcall RtwqInvokeCallback(ptr) -@ stub RtwqJoinWorkQueue +@ stdcall RtwqJoinWorkQueue(long long ptr) @ stdcall RtwqLockPlatform() @ stdcall RtwqLockSharedWorkQueue(wstr long ptr ptr) @ stdcall RtwqLockWorkQueue(long) @@ -30,7 +30,7 @@ @ stdcall RtwqSetLongRunning(long long) @ stdcall RtwqShutdown() @ stdcall RtwqStartup() -@ stub RtwqUnjoinWorkQueue +@ stdcall RtwqUnjoinWorkQueue(long long) @ stdcall RtwqUnlockPlatform() @ stdcall RtwqUnlockWorkQueue(long) @ stub RtwqUnregisterPlatformEvents diff --git a/include/rtworkq.idl b/include/rtworkq.idl index 1a452c3edc..ca6645b862 100644 --- a/include/rtworkq.idl +++ b/include/rtworkq.idl @@ -84,6 +84,7 @@ cpp_quote("HRESULT WINAPI RtwqCancelDeadline(HANDLE request);") cpp_quote("HRESULT WINAPI RtwqCancelWorkItem(RTWQWORKITEM_KEY key);") cpp_quote("HRESULT WINAPI RtwqCreateAsyncResult(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **result);") cpp_quote("HRESULT WINAPI RtwqInvokeCallback(IRtwqAsyncResult *result);") +cpp_quote("HRESULT WINAPI RtwqJoinWorkQueue(DWORD queue, HANDLE hFile, HANDLE *cookie);") cpp_quote("HRESULT WINAPI RtwqLockPlatform(void);") cpp_quote("HRESULT WINAPI RtwqLockSharedWorkQueue(const WCHAR *usageclass, LONG priority, DWORD *taskid, DWORD *queue);") cpp_quote("HRESULT WINAPI RtwqLockWorkQueue(DWORD queue);") @@ -96,5 +97,6 @@ cpp_quote("HRESULT WINAPI RtwqSetDeadline2(DWORD queue_id, LONGLONG deadline, LO cpp_quote("HRESULT WINAPI RtwqSetLongRunning(DWORD queue_id, BOOL enable);") cpp_quote("HRESULT WINAPI RtwqShutdown(void);") cpp_quote("HRESULT WINAPI RtwqStartup(void);") +cpp_quote("HRESULT WINAPI RtwqUnjoinWorkQueue(DWORD queue, HANDLE cookie);") cpp_quote("HRESULT WINAPI RtwqUnlockPlatform(void);") cpp_quote("HRESULT WINAPI RtwqUnlockWorkQueue(DWORD queue);")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mfplat.spec | 8 ++++-- dlls/rtworkq/queue.c | 57 +++++++++++++++++++++++++++++++++++++++ dlls/rtworkq/rtworkq.spec | 16 +++++------ include/mfapi.h | 7 +++++ include/rtworkq.idl | 20 ++++++++++++++ 5 files changed, 98 insertions(+), 10 deletions(-)
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index 5311757d2b..25e5f62f21 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -24,6 +24,7 @@ @ stdcall MFBeginCreateFile(long long long wstr ptr ptr ptr) @ stub MFBeginGetHostByName @ stub MFBeginRegisterWorkQueueWithMMCSS +@ stdcall MFBeginRegisterWorkQueueWithMMCSSEx(long wstr long long ptr ptr) rtworkq.RtwqBeginRegisterWorkQueueWithMMCSS @ stub MFBeginUnregisterWorkQueueWithMMCSS @ stub MFBlockThread @ stub MFCalculateBitmapImageSize @@ -107,8 +108,9 @@ @ stdcall MFGetSystemTime() @ stdcall MFGetTimerPeriodicity(ptr) @ stub MFGetUncompressedVideoFormat -@ stub MFGetWorkQueueMMCSSClass -@ stub MFGetWorkQueueMMCSSTaskId +@ stdcall MFGetWorkQueueMMCSSClass(long ptr ptr) rtworkq.RtwqGetWorkQueueMMCSSClass +@ stdcall MFGetWorkQueueMMCSSTaskId(long ptr) rtworkq.RtwqGetWorkQueueMMCSSTaskId +@ stdcall MFGetWorkQueueMMCSSPriority(long ptr) rtworkq.RtwqGetWorkQueueMMCSSPriority @ stdcall MFHeapAlloc(long long str long long) @ stdcall MFHeapFree(ptr) @ stub MFInitAMMediaTypeFromMFMediaType @@ -135,6 +137,7 @@ @ stub MFRecordError @ stdcall MFRegisterLocalByteStreamHandler(wstr wstr ptr) @ stdcall MFRegisterLocalSchemeHandler(wstr ptr) +@ stdcall MFRegisterPlatformWithMMCSS(wstr ptr long) rtworkq.RtwqRegisterPlatformWithMMCSS @ stdcall MFRemovePeriodicCallback(long) rtworkq.RtwqRemovePeriodicCallback @ stdcall MFScheduleWorkItem(ptr ptr int64 ptr) @ stdcall MFScheduleWorkItemEx(ptr int64 ptr) rtworkq.RtwqScheduleWorkItem @@ -156,6 +159,7 @@ @ stdcall MFTUnregister(int128) @ stdcall MFTUnregisterLocal(ptr) @ stdcall MFTUnregisterLocalByCLSID(int128) +@ stdcall MFUnregisterPlatformFromMMCSS() rtworkq.RtwqUnregisterPlatformFromMMCSS @ stub MFTraceError @ stub MFTraceFuncEnter @ stub MFUnblockThread diff --git a/dlls/rtworkq/queue.c b/dlls/rtworkq/queue.c index 32bd75b346..ce06df1c8c 100644 --- a/dlls/rtworkq/queue.c +++ b/dlls/rtworkq/queue.c @@ -1485,3 +1485,60 @@ HRESULT WINAPI RtwqUnjoinWorkQueue(DWORD queue, HANDLE cookie)
return E_NOTIMPL; } + +HRESULT WINAPI RtwqGetWorkQueueMMCSSClass(DWORD queue, WCHAR *class, DWORD *length) +{ + FIXME("%#x, %p, %p.\n", queue, class, length); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqGetWorkQueueMMCSSTaskId(DWORD queue, DWORD *taskid) +{ + FIXME("%#x, %p.\n", queue, taskid); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqGetWorkQueueMMCSSPriority(DWORD queue, LONG *priority) +{ + FIXME("%#x, %p.\n", queue, priority); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqRegisterPlatformWithMMCSS(const WCHAR *class, DWORD *taskid, LONG priority) +{ + FIXME("%s, %p, %d.\n", debugstr_w(class), taskid, priority); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqUnregisterPlatformFromMMCSS(void) +{ + FIXME("\n"); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqBeginRegisterWorkQueueWithMMCSS(DWORD queue, const WCHAR *class, DWORD taskid, LONG priority, + IRtwqAsyncCallback *callback, IUnknown *state) +{ + FIXME("%#x, %s, %u, %d, %p, %p.\n", queue, debugstr_w(class), taskid, priority, callback, state); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqRegisterPlatformEvents(IRtwqPlatformEvents *events) +{ + FIXME("%p.\n", events); + + return E_NOTIMPL; +} + +HRESULT WINAPI RtwqUnregisterPlatformEvents(IRtwqPlatformEvents *events) +{ + FIXME("%p.\n", events); + + return E_NOTIMPL; +} diff --git a/dlls/rtworkq/rtworkq.spec b/dlls/rtworkq/rtworkq.spec index 11955ac1a6..09d877790d 100644 --- a/dlls/rtworkq/rtworkq.spec +++ b/dlls/rtworkq/rtworkq.spec @@ -1,7 +1,7 @@ @ stdcall RtwqAddPeriodicCallback(ptr ptr ptr) @ stdcall RtwqAllocateSerialWorkQueue(long ptr) @ stdcall RtwqAllocateWorkQueue(long ptr) -@ stub RtwqBeginRegisterWorkQueueWithMMCSS +@ stdcall RtwqBeginRegisterWorkQueueWithMMCSS(long wstr long long ptr ptr) @ stub RtwqBeginUnregisterWorkQueueWithMMCSS @ stdcall RtwqCancelDeadline(long) @ stub RtwqCancelMultipleWaitingWorkItem @@ -10,9 +10,9 @@ @ stub RtwqEndRegisterWorkQueueWithMMCSS @ stub RtwqEndUnregisterWorkQueueWithMMCSS @ stub RtwqGetPlatform -@ stub RtwqGetWorkQueueMMCSSClass -@ stub RtwqGetWorkQueueMMCSSPriority -@ stub RtwqGetWorkQueueMMCSSTaskId +@ stdcall RtwqGetWorkQueueMMCSSClass(long ptr ptr) +@ stdcall RtwqGetWorkQueueMMCSSPriority(long ptr) +@ stdcall RtwqGetWorkQueueMMCSSTaskId(long ptr) @ stdcall RtwqInvokeCallback(ptr) @ stdcall RtwqJoinWorkQueue(long long ptr) @ stdcall RtwqLockPlatform() @@ -21,8 +21,8 @@ @ stub RtwqPutMultipleWaitingWorkItem @ stdcall RtwqPutWaitingWorkItem(long long ptr ptr) @ stdcall RtwqPutWorkItem(long long ptr) -@ stub RtwqRegisterPlatformEvents -@ stub RtwqRegisterPlatformWithMMCSS +@ stdcall RtwqRegisterPlatformEvents(ptr) +@ stdcall RtwqRegisterPlatformWithMMCSS(wstr ptr long) @ stdcall RtwqRemovePeriodicCallback(long) @ stdcall RtwqScheduleWorkItem(ptr int64 ptr) @ stdcall RtwqSetDeadline(long int64 ptr) @@ -33,5 +33,5 @@ @ stdcall RtwqUnjoinWorkQueue(long long) @ stdcall RtwqUnlockPlatform() @ stdcall RtwqUnlockWorkQueue(long) -@ stub RtwqUnregisterPlatformEvents -@ stub RtwqUnregisterPlatformFromMMCSS +@ stdcall RtwqUnregisterPlatformEvents(ptr) +@ stdcall RtwqUnregisterPlatformFromMMCSS() diff --git a/include/mfapi.h b/include/mfapi.h index f83b7636fe..b9383630ab 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -488,6 +488,8 @@ HRESULT WINAPI MFAllocateWorkQueue(DWORD *queue); HRESULT WINAPI MFAllocateWorkQueueEx(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue); HRESULT WINAPI MFBeginCreateFile(MF_FILE_ACCESSMODE access_mode, MF_FILE_OPENMODE open_mode, MF_FILE_FLAGS flags, const WCHAR *path, IMFAsyncCallback *callback, IUnknown *state, IUnknown **cancel_cookie); +HRESULT WINAPI MFBeginRegisterWorkQueueWithMMCSSEx(DWORD queue, const WCHAR *usage_class, DWORD taskid, LONG priority, + IMFAsyncCallback *callback, IUnknown *state); HRESULT WINAPI MFCalculateImageSize(REFGUID subtype, UINT32 width, UINT32 height, UINT32 *size); HRESULT WINAPI MFCancelCreateFile(IUnknown *cancel_cookie); HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key); @@ -518,6 +520,9 @@ HRESULT WINAPI MFGetAttributesAsBlobSize(IMFAttributes *attributes, UINT32 *size HRESULT WINAPI MFGetStrideForBitmapInfoHeader(DWORD format, DWORD width, LONG *stride); HRESULT WINAPI MFGetPlaneSize(DWORD format, DWORD width, DWORD height, DWORD *size); HRESULT WINAPI MFGetTimerPeriodicity(DWORD *periodicity); +HRESULT WINAPI MFGetWorkQueueMMCSSClass(DWORD queue, WCHAR *class, DWORD *length); +HRESULT WINAPI MFGetWorkQueueMMCSSPriority(DWORD queue, LONG *priority); +HRESULT WINAPI MFGetWorkQueueMMCSSTaskId(DWORD queue, DWORD *taskid); HRESULT WINAPI MFTEnum(GUID category, UINT32 flags, MFT_REGISTER_TYPE_INFO *input_type, MFT_REGISTER_TYPE_INFO *output_type, IMFAttributes *attributes, CLSID **pclsids, UINT32 *pcount); @@ -535,6 +540,7 @@ HRESULT WINAPI MFPutWorkItemEx(DWORD queue, IMFAsyncResult *result); HRESULT WINAPI MFPutWorkItemEx2(DWORD queue, LONG priority, IMFAsyncResult *result); HRESULT WINAPI MFRegisterLocalByteStreamHandler(const WCHAR *extension, const WCHAR *mime, IMFActivate *activate); HRESULT WINAPI MFRegisterLocalSchemeHandler(const WCHAR *scheme, IMFActivate *activate); +HRESULT WINAPI MFRegisterPlatformWithMMCSS(const WCHAR *usage_class, DWORD *taskid, LONG priority); HRESULT WINAPI MFScheduleWorkItem(IMFAsyncCallback *callback, IUnknown *state, INT64 timeout, MFWORKITEM_KEY *key); HRESULT WINAPI MFScheduleWorkItemEx(IMFAsyncResult *result, INT64 timeout, MFWORKITEM_KEY *key); HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags, UINT32 cinput, @@ -551,6 +557,7 @@ HRESULT WINAPI MFShutdown(void); HRESULT WINAPI MFStartup(ULONG version, DWORD flags); HRESULT WINAPI MFUnlockPlatform(void); HRESULT WINAPI MFUnlockWorkQueue(DWORD queue); +HRESULT WINAPI MFUnregisterPlatformFromMMCSS(void); HRESULT WINAPI MFTUnregister(CLSID clsid); HRESULT WINAPI MFTUnregisterLocal(IClassFactory *factory); HRESULT WINAPI MFTUnregisterLocalByCLSID(CLSID clsid); diff --git a/include/rtworkq.idl b/include/rtworkq.idl index ca6645b862..ed32df1c3b 100644 --- a/include/rtworkq.idl +++ b/include/rtworkq.idl @@ -52,6 +52,18 @@ interface IRtwqAsyncCallback : IUnknown HRESULT Invoke([in] IRtwqAsyncResult *result); }
+[ + object, + uuid(63d9255a-7ff1-4b61-8faf-ed6460dacf2b), + local +] +interface IRtwqPlatformEvents : IUnknown +{ + HRESULT InitializationComplete(void); + HRESULT ShutdownStart(void); + HRESULT ShutdownComplete(void); +} + cpp_quote("#define RTWQ_E_ERROR(x) ((HRESULT)(0xc00d0000L+x))") cpp_quote("#define RTWQ_E_BUFFERTOOSMALL RTWQ_E_ERROR(14001)") cpp_quote("#define RTWQ_E_NOT_INITIALIZED RTWQ_E_ERROR(14006)") @@ -80,9 +92,13 @@ cpp_quote("typedef void (WINAPI *RTWQPERIODICCALLBACK)(IUnknown *context);") cpp_quote("HRESULT WINAPI RtwqAddPeriodicCallback(RTWQPERIODICCALLBACK callback, IUnknown *context, DWORD *key);") cpp_quote("HRESULT WINAPI RtwqAllocateSerialWorkQueue(DWORD target_queue, DWORD *queue);") cpp_quote("HRESULT WINAPI RtwqAllocateWorkQueue(RTWQ_WORKQUEUE_TYPE queue_type, DWORD *queue);") +cpp_quote("HRESULT WINAPI RtwqBeginRegisterWorkQueueWithMMCSS(DWORD queue, const WCHAR *class, DWORD taskid, LONG priority, IRtwqAsyncCallback *callback, IUnknown *state);") cpp_quote("HRESULT WINAPI RtwqCancelDeadline(HANDLE request);") cpp_quote("HRESULT WINAPI RtwqCancelWorkItem(RTWQWORKITEM_KEY key);") cpp_quote("HRESULT WINAPI RtwqCreateAsyncResult(IUnknown *object, IRtwqAsyncCallback *callback, IUnknown *state, IRtwqAsyncResult **result);") +cpp_quote("HRESULT WINAPI RtwqGetWorkQueueMMCSSClass(DWORD queue, WCHAR *class, DWORD *length);") +cpp_quote("HRESULT WINAPI RtwqGetWorkQueueMMCSSPriority(DWORD queue, LONG *priority);") +cpp_quote("HRESULT WINAPI RtwqGetWorkQueueMMCSSTaskId(DWORD queue, DWORD *taskid);") cpp_quote("HRESULT WINAPI RtwqInvokeCallback(IRtwqAsyncResult *result);") cpp_quote("HRESULT WINAPI RtwqJoinWorkQueue(DWORD queue, HANDLE hFile, HANDLE *cookie);") cpp_quote("HRESULT WINAPI RtwqLockPlatform(void);") @@ -90,6 +106,8 @@ cpp_quote("HRESULT WINAPI RtwqLockSharedWorkQueue(const WCHAR *usageclass, LONG cpp_quote("HRESULT WINAPI RtwqLockWorkQueue(DWORD queue);") cpp_quote("HRESULT WINAPI RtwqPutWaitingWorkItem(HANDLE event, LONG priority, IRtwqAsyncResult *result, RTWQWORKITEM_KEY *key);") cpp_quote("HRESULT WINAPI RtwqPutWorkItem(DWORD queue, LONG priority, IRtwqAsyncResult *result);") +cpp_quote("HRESULT WINAPI RtwqRegisterPlatformEvents(IRtwqPlatformEvents *events);") +cpp_quote("HRESULT WINAPI RtwqRegisterPlatformWithMMCSS(const WCHAR *class, DWORD *taskid, LONG priority);") cpp_quote("HRESULT WINAPI RtwqRemovePeriodicCallback(DWORD key);") cpp_quote("HRESULT WINAPI RtwqScheduleWorkItem(IRtwqAsyncResult *result, INT64 timeout, RTWQWORKITEM_KEY *key);") cpp_quote("HRESULT WINAPI RtwqSetDeadline(DWORD queue_id, LONGLONG deadline, HANDLE *request);") @@ -100,3 +118,5 @@ cpp_quote("HRESULT WINAPI RtwqStartup(void);") cpp_quote("HRESULT WINAPI RtwqUnjoinWorkQueue(DWORD queue, HANDLE cookie);") cpp_quote("HRESULT WINAPI RtwqUnlockPlatform(void);") cpp_quote("HRESULT WINAPI RtwqUnlockWorkQueue(DWORD queue);") +cpp_quote("HRESULT WINAPI RtwqUnregisterPlatformEvents(IRtwqPlatformEvents *events);") +cpp_quote("HRESULT WINAPI RtwqUnregisterPlatformFromMMCSS(void);")