Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/queue.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index 66f8588f82..e579168770 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -62,7 +62,7 @@ struct work_item struct queue { TP_POOL *pool; - TP_CALLBACK_ENVIRON env; + TP_CALLBACK_ENVIRON_V3 env; CRITICAL_SECTION cs; struct list pending_items; }; @@ -163,10 +163,13 @@ static void init_work_queue(MFASYNC_WORKQUEUE_TYPE queue_type, struct queue *que unsigned int max_thread;
queue->pool = CreateThreadpool(NULL); - queue->env.Version = 1; + memset(&queue->env, 0, sizeof(queue->env)); + queue->env.Version = 3; + queue->env.Size = sizeof(queue->env); queue->env.Pool = queue->pool; queue->env.CleanupGroup = CreateThreadpoolCleanupGroup(); queue->env.CleanupGroupCancelCallback = standard_queue_cleanup_callback; + queue->env.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL; list_init(&queue->pending_items); InitializeCriticalSection(&queue->cs);
@@ -344,7 +347,7 @@ static HRESULT queue_submit_item(struct queue *queue, IMFAsyncResult *result) if (!(item = alloc_work_item(queue, result))) return E_OUTOFMEMORY;
- work_object = CreateThreadpoolWork(standard_queue_worker, item, &queue->env); + work_object = CreateThreadpoolWork(standard_queue_worker, item, (TP_CALLBACK_ENVIRON *)&queue->env); SubmitThreadpoolWork(work_object);
TRACE("dispatched %p.\n", result); @@ -483,7 +486,7 @@ static HRESULT queue_submit_wait(struct queue *queue, HANDLE event, LONG priorit else callback = waiting_item_callback;
- item->u.wait_object = CreateThreadpoolWait(callback, item, &queue->env); + item->u.wait_object = CreateThreadpoolWait(callback, item, (TP_CALLBACK_ENVIRON *)&queue->env); SetThreadpoolWait(item->u.wait_object, event, NULL);
TRACE("dispatched %p.\n", result); @@ -516,7 +519,7 @@ static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, I filetime.dwLowDateTime = t.u.LowPart; filetime.dwHighDateTime = t.u.HighPart;
- item->u.timer_object = CreateThreadpoolTimer(callback, item, &queue->env); + item->u.timer_object = CreateThreadpoolTimer(callback, item, (TP_CALLBACK_ENVIRON *)&queue->env); SetThreadpoolTimer(item->u.timer_object, &filetime, period, 0);
TRACE("dispatched %p.\n", result);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mfplat.spec | 2 + dlls/mfplat/queue.c | 92 ++++++++++++++++++++++++++++++++--------- include/mfapi.h | 2 + 3 files changed, 77 insertions(+), 19 deletions(-)
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index c47af72ed8..be5d8b2205 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -123,7 +123,9 @@ @ stdcall MFLockWorkQueue(long) @ stdcall MFPutWaitingWorkItem(long long ptr ptr) @ stdcall MFPutWorkItem(long ptr ptr) +@ stdcall MFPutWorkItem2(long long ptr ptr) @ stdcall MFPutWorkItemEx(long ptr) +@ stdcall MFPutWorkItemEx2(long long ptr) @ stub MFRecordError @ stdcall MFRemovePeriodicCallback(long) @ stdcall MFScheduleWorkItem(ptr ptr int64 ptr) diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index e579168770..c2cc6233b5 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -59,10 +59,17 @@ struct work_item } u; };
+static const TP_CALLBACK_PRIORITY priorities[] = +{ + TP_CALLBACK_PRIORITY_HIGH, + TP_CALLBACK_PRIORITY_NORMAL, + TP_CALLBACK_PRIORITY_LOW, +}; + struct queue { TP_POOL *pool; - TP_CALLBACK_ENVIRON_V3 env; + TP_CALLBACK_ENVIRON_V3 envs[ARRAY_SIZE(priorities)]; CRITICAL_SECTION cs; struct list pending_items; }; @@ -160,16 +167,23 @@ static void release_work_item(struct work_item *item)
static void init_work_queue(MFASYNC_WORKQUEUE_TYPE queue_type, struct queue *queue) { - unsigned int max_thread; + TP_CALLBACK_ENVIRON_V3 env; + unsigned int max_thread, i;
queue->pool = CreateThreadpool(NULL); - memset(&queue->env, 0, sizeof(queue->env)); - queue->env.Version = 3; - queue->env.Size = sizeof(queue->env); - queue->env.Pool = queue->pool; - queue->env.CleanupGroup = CreateThreadpoolCleanupGroup(); - queue->env.CleanupGroupCancelCallback = standard_queue_cleanup_callback; - queue->env.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL; + + memset(&env, 0, sizeof(env)); + env.Version = 3; + env.Size = sizeof(env); + env.Pool = queue->pool; + env.CleanupGroup = CreateThreadpoolCleanupGroup(); + env.CleanupGroupCancelCallback = standard_queue_cleanup_callback; + env.CallbackPriority = TP_CALLBACK_PRIORITY_NORMAL; + for (i = 0; i < ARRAY_SIZE(queue->envs); ++i) + { + queue->envs[i] = env; + queue->envs[i].CallbackPriority = priorities[i]; + } list_init(&queue->pending_items); InitializeCriticalSection(&queue->cs);
@@ -267,7 +281,7 @@ static void shutdown_queue(struct queue *queue) if (!queue->pool) return;
- CloseThreadpoolCleanupGroupMembers(queue->env.CleanupGroup, TRUE, NULL); + CloseThreadpoolCleanupGroupMembers(queue->envs[0].CleanupGroup, TRUE, NULL); CloseThreadpool(queue->pool); queue->pool = NULL;
@@ -339,15 +353,23 @@ static void CALLBACK standard_queue_worker(TP_CALLBACK_INSTANCE *instance, void release_work_item(item); }
-static HRESULT queue_submit_item(struct queue *queue, IMFAsyncResult *result) +static HRESULT queue_submit_item(struct queue *queue, LONG priority, IMFAsyncResult *result) { + TP_CALLBACK_PRIORITY callback_priority; struct work_item *item; TP_WORK *work_object;
if (!(item = alloc_work_item(queue, result))) return E_OUTOFMEMORY;
- work_object = CreateThreadpoolWork(standard_queue_worker, item, (TP_CALLBACK_ENVIRON *)&queue->env); + if (priority == 0) + callback_priority = TP_CALLBACK_PRIORITY_NORMAL; + else if (priority < 0) + callback_priority = TP_CALLBACK_PRIORITY_LOW; + else + callback_priority = TP_CALLBACK_PRIORITY_HIGH; + work_object = CreateThreadpoolWork(standard_queue_worker, item, + (TP_CALLBACK_ENVIRON *)&queue->envs[callback_priority]); SubmitThreadpoolWork(work_object);
TRACE("dispatched %p.\n", result); @@ -355,7 +377,7 @@ static HRESULT queue_submit_item(struct queue *queue, IMFAsyncResult *result) return S_OK; }
-static HRESULT queue_put_work_item(DWORD queue_id, IMFAsyncResult *result) +static HRESULT queue_put_work_item(DWORD queue_id, LONG priority, IMFAsyncResult *result) { struct queue *queue; HRESULT hr; @@ -363,7 +385,7 @@ static HRESULT queue_put_work_item(DWORD queue_id, IMFAsyncResult *result) if (FAILED(hr = grab_queue(queue_id, &queue))) return hr;
- hr = queue_submit_item(queue, result); + hr = queue_submit_item(queue, priority, result);
return hr; } @@ -380,7 +402,7 @@ static HRESULT invoke_async_callback(IMFAsyncResult *result) if (FAILED(lock_user_queue(queue))) queue = MFASYNC_CALLBACK_QUEUE_STANDARD;
- hr = queue_put_work_item(queue, result); + hr = queue_put_work_item(queue, 0, result);
unlock_user_queue(queue);
@@ -486,7 +508,8 @@ static HRESULT queue_submit_wait(struct queue *queue, HANDLE event, LONG priorit else callback = waiting_item_callback;
- item->u.wait_object = CreateThreadpoolWait(callback, item, (TP_CALLBACK_ENVIRON *)&queue->env); + item->u.wait_object = CreateThreadpoolWait(callback, item, + (TP_CALLBACK_ENVIRON *)&queue->envs[TP_CALLBACK_PRIORITY_NORMAL]); SetThreadpoolWait(item->u.wait_object, event, NULL);
TRACE("dispatched %p.\n", result); @@ -519,7 +542,8 @@ static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, I filetime.dwLowDateTime = t.u.LowPart; filetime.dwHighDateTime = t.u.HighPart;
- item->u.timer_object = CreateThreadpoolTimer(callback, item, (TP_CALLBACK_ENVIRON *)&queue->env); + item->u.timer_object = CreateThreadpoolTimer(callback, item, + (TP_CALLBACK_ENVIRON *)&queue->envs[TP_CALLBACK_PRIORITY_NORMAL]); SetThreadpoolTimer(item->u.timer_object, &filetime, period, 0);
TRACE("dispatched %p.\n", result); @@ -828,7 +852,27 @@ HRESULT WINAPI MFPutWorkItem(DWORD queue, IMFAsyncCallback *callback, IUnknown * if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result))) return hr;
- hr = queue_put_work_item(queue, result); + hr = queue_put_work_item(queue, 0, result); + + IMFAsyncResult_Release(result); + + return hr; +} + +/*********************************************************************** + * MFPutWorkItem2 (mfplat.@) + */ +HRESULT WINAPI MFPutWorkItem2(DWORD queue, LONG priority, IMFAsyncCallback *callback, IUnknown *state) +{ + IMFAsyncResult *result; + HRESULT hr; + + TRACE("%#x, %d, %p, %p.\n", queue, priority, callback, state); + + if (FAILED(hr = MFCreateAsyncResult(NULL, callback, state, &result))) + return hr; + + hr = queue_put_work_item(queue, priority, result);
IMFAsyncResult_Release(result);
@@ -842,7 +886,17 @@ HRESULT WINAPI MFPutWorkItemEx(DWORD queue, IMFAsyncResult *result) { TRACE("%#x, %p\n", queue, result);
- return queue_put_work_item(queue, result); + return queue_put_work_item(queue, 0, result); +} + +/*********************************************************************** + * MFPutWorkItemEx2 (mfplat.@) + */ +HRESULT WINAPI MFPutWorkItemEx2(DWORD queue, LONG priority, IMFAsyncResult *result) +{ + TRACE("%#x, %d, %p\n", queue, priority, result); + + return queue_put_work_item(queue, priority, result); }
/*********************************************************************** diff --git a/include/mfapi.h b/include/mfapi.h index fd5fbebc58..21876fe574 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -173,7 +173,9 @@ HRESULT WINAPI MFTEnumEx(GUID category, UINT32 flags, const MFT_REGISTER_TYPE_IN HRESULT WINAPI MFInvokeCallback(IMFAsyncResult *result); HRESULT WINAPI MFLockPlatform(void); HRESULT WINAPI MFPutWorkItem(DWORD queue, IMFAsyncCallback *callback, IUnknown *state); +HRESULT WINAPI MFPutWorkItem2(DWORD queue, LONG priority, IMFAsyncCallback *callback, IUnknown *state); HRESULT WINAPI MFPutWorkItemEx(DWORD queue, IMFAsyncResult *result); +HRESULT WINAPI MFPutWorkItemEx2(DWORD queue, LONG priority, IMFAsyncResult *result); 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,
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/main.c | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c index 88903ceddf..6b6c5167ff 100644 --- a/dlls/mfreadwrite/main.c +++ b/dlls/mfreadwrite/main.c @@ -70,10 +70,11 @@ HRESULT WINAPI DllUnregisterServer(void) return __wine_unregister_resources( mfinstance ); }
-typedef struct _srcreader +typedef struct source_reader { IMFSourceReader IMFSourceReader_iface; - LONG ref; + LONG refcount; + IMFMediaSource *source; } srcreader;
struct sink_writer @@ -117,7 +118,7 @@ static HRESULT WINAPI src_reader_QueryInterface(IMFSourceReader *iface, REFIID r static ULONG WINAPI src_reader_AddRef(IMFSourceReader *iface) { srcreader *This = impl_from_IMFSourceReader(iface); - ULONG ref = InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->refcount);
TRACE("(%p) ref=%u\n", This, ref);
@@ -126,17 +127,18 @@ static ULONG WINAPI src_reader_AddRef(IMFSourceReader *iface)
static ULONG WINAPI src_reader_Release(IMFSourceReader *iface) { - srcreader *This = impl_from_IMFSourceReader(iface); - ULONG ref = InterlockedDecrement(&This->ref); + struct source_reader *reader = impl_from_IMFSourceReader(iface); + ULONG refcount = InterlockedDecrement(&reader->refcount);
- TRACE("(%p) ref=%u\n", This, ref); + TRACE("%p, refcount %d.\n", iface, refcount);
- if (!ref) + if (!refcount) { - HeapFree(GetProcessHeap(), 0, This); + IMFMediaSource_Release(reader->source); + heap_free(reader); }
- return ref; + return refcount; }
static HRESULT WINAPI src_reader_GetStreamSelection(IMFSourceReader *iface, DWORD index, BOOL *selected) @@ -244,7 +246,9 @@ static HRESULT create_source_reader_from_source(IMFMediaSource *source, IMFAttri return E_OUTOFMEMORY;
object->IMFSourceReader_iface.lpVtbl = &srcreader_vtbl; - object->ref = 1; + object->refcount = 1; + object->source = source; + IMFMediaSource_AddRef(object->source);
hr = IMFSourceReader_QueryInterface(&object->IMFSourceReader_iface, riid, out); IMFSourceReader_Release(&object->IMFSourceReader_iface);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfreadwrite/main.c | 35 ++++++++++++++++++++++++++++++++--- include/mfreadwrite.idl | 2 ++ 2 files changed, 34 insertions(+), 3 deletions(-)
diff --git a/dlls/mfreadwrite/main.c b/dlls/mfreadwrite/main.c index 6b6c5167ff..f3fd3b293d 100644 --- a/dlls/mfreadwrite/main.c +++ b/dlls/mfreadwrite/main.c @@ -21,6 +21,7 @@ #include <stdarg.h>
#define COBJMACROS +#define NONAMELESSUNION
#include "windef.h" #include "winbase.h" @@ -211,10 +212,38 @@ static HRESULT WINAPI src_reader_GetServiceForStream(IMFSourceReader *iface, DWO }
static HRESULT WINAPI src_reader_GetPresentationAttribute(IMFSourceReader *iface, DWORD index, - REFGUID guid, PROPVARIANT *attr) + REFGUID guid, PROPVARIANT *value) { - srcreader *This = impl_from_IMFSourceReader(iface); - FIXME("%p, 0x%08x, %s, %p\n", This, index, debugstr_guid(guid), attr); + struct source_reader *reader = impl_from_IMFSourceReader(iface); + HRESULT hr; + + TRACE("%p, %#x, %s, %p.\n", iface, index, debugstr_guid(guid), value); + + switch (index) + { + case MF_SOURCE_READER_MEDIASOURCE: + if (IsEqualGUID(guid, &MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS)) + { + DWORD flags; + + if (FAILED(hr = IMFMediaSource_GetCharacteristics(reader->source, &flags))) + return hr; + + value->vt = VT_UI4; + value->u.ulVal = flags; + return S_OK; + } + else + { + FIXME("Unsupported source attribute %s.\n", debugstr_guid(guid)); + return E_NOTIMPL; + } + break; + default: + FIXME("Unsupported index %#x.\n", index); + return E_NOTIMPL; + } + return E_NOTIMPL; }
diff --git a/include/mfreadwrite.idl b/include/mfreadwrite.idl index 264712778f..9097b5a548 100644 --- a/include/mfreadwrite.idl +++ b/include/mfreadwrite.idl @@ -78,6 +78,8 @@ cpp_quote("EXTERN_GUID(MF_READWRITE_MMCSS_CLASS_AUDIO, 0x430847da, 0x08 cpp_quote("EXTERN_GUID(MF_READWRITE_MMCSS_PRIORITY_AUDIO, 0x273db885, 0x2de2, 0x4db2, 0xa6, 0xa7, 0xfd, 0xb6, 0x6f, 0xb4, 0x0b, 0x61);") cpp_quote("EXTERN_GUID(MF_READWRITE_D3D_OPTIONAL, 0x216479d9, 0x3071, 0x42ca, 0xbb, 0x6c, 0x4c, 0x22, 0x10, 0x2e, 0x1d, 0x18);")
+cpp_quote("EXTERN_GUID(MF_SOURCE_READER_MEDIASOURCE_CHARACTERISTICS, 0x6d23f5c8, 0xc5d7, 0x4a9b, 0x99, 0x71, 0x5d, 0x11, 0xf8, 0xbc, 0xa8, 0x80);") + interface IMFMediaSource;
[
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index f12666f053..c7f4fea6b4 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -2930,11 +2930,8 @@ static HRESULT WINAPI mfmediaevent_GetItemByIndex(IMFMediaEvent *iface, UINT32 i
static HRESULT WINAPI mfmediaevent_CopyAllItems(IMFMediaEvent *iface, IMFAttributes *dest) { - mfmediaevent *This = impl_from_IMFMediaEvent(iface); - - FIXME("%p, %p\n", This, dest); - - return E_NOTIMPL; + struct media_event *event = impl_from_IMFMediaEvent(iface); + return IMFAttributes_CopyAllItems(&event->attributes.IMFAttributes_iface, dest); }
static HRESULT WINAPI mfmediaevent_GetType(IMFMediaEvent *iface, MediaEventType *type)
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=49243
Your paranoid android.
=== debian9 (32 bit report) ===
mfplat: mfplat.c:1838: Test failed: Unexpected refcount 1. Unhandled exception: page fault on read access to 0x00000008 in 32-bit code (0x7e78546a).
Report errors: mfplat:mfplat crashed (c0000005)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 27ca405175..d27d5ef12b 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -750,9 +750,8 @@ static HRESULT WINAPI stream_descriptor_GetItemByIndex(IMFStreamDescriptor *ifac
static HRESULT WINAPI stream_descriptor_CopyAllItems(IMFStreamDescriptor *iface, IMFAttributes *dest) { - FIXME("%p, %p.\n", iface, dest); - - return E_NOTIMPL; + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_CopyAllItems(&stream_desc->attributes.IMFAttributes_iface, dest); }
static HRESULT WINAPI stream_descriptor_GetStreamIdentifier(IMFStreamDescriptor *iface, DWORD *identifier)
Hi,
While running your changed tests on Windows, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=49239
Your paranoid android.
=== debian9 (32 bit Chinese:China report) ===
mfplat: Unhandled exception: page fault on read access to 0x00000017 in 32-bit code (0x7e5da31a).