Signed-off-by: Nikolay Sivov nsivov@codeweavers.com ---
v2: test inconsistently crashing on XP removed for now.
dlls/mfplat/mfplat.spec | 6 +- dlls/mfplat/queue.c | 194 +++++++++++++++++++++++++++++++++++-- dlls/mfplat/tests/mfplat.c | 48 +++++++++ include/mfapi.h | 4 + 4 files changed, 242 insertions(+), 10 deletions(-)
diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index c6234b006e..116ec61289 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -15,7 +15,7 @@ @ stub GetAMSubtypeFromD3DFormat @ stub GetD3DFormatFromMFSubtype @ stub LFGetGlobalPool -@ stub MFAddPeriodicCallback +@ stdcall MFAddPeriodicCallback(ptr ptr ptr) @ stdcall MFAllocateWorkQueue(ptr) @ stdcall MFAllocateWorkQueueEx(long ptr) @ stub MFAppendCollection @@ -100,7 +100,7 @@ @ stub MFGetSockaddrFromNumericName @ stub MFGetStrideForBitmapInfoHeader @ stdcall MFGetSystemTime() -@ stub MFGetTimerPeriodicity +@ stdcall MFGetTimerPeriodicity(ptr) @ stub MFGetUncompressedVideoFormat @ stub MFGetWorkQueueMMCSSClass @ stub MFGetWorkQueueMMCSSTaskId @@ -125,7 +125,7 @@ @ stdcall MFPutWorkItem(long ptr ptr) @ stdcall MFPutWorkItemEx(long ptr) @ stub MFRecordError -@ stub MFRemovePeriodicCallback +@ stdcall MFRemovePeriodicCallback(long) @ stdcall MFScheduleWorkItem(ptr ptr int64 ptr) @ stdcall MFScheduleWorkItemEx(ptr int64 ptr) @ stub MFSerializeAttributesToStream diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index f470cb44b5..e3b0687711 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -39,9 +39,14 @@ WINE_DEFAULT_DEBUG_CHANNEL(mfplat);
static LONG next_item_key;
+static MFWORKITEM_KEY get_item_key(DWORD mask, DWORD key) +{ + return ((MFWORKITEM_KEY)mask << 32) | key; +} + static MFWORKITEM_KEY generate_item_key(DWORD mask) { - return ((MFWORKITEM_KEY)mask << 32) | InterlockedIncrement(&next_item_key); + return get_item_key(mask, InterlockedIncrement(&next_item_key)); }
struct work_item @@ -315,9 +320,10 @@ void shutdown_system_queues(void) LeaveCriticalSection(&queues_section); }
-static void grab_work_item(struct work_item *item) +static struct work_item *grab_work_item(struct work_item *item) { InterlockedIncrement(&item->refcount); + return item; }
static void CALLBACK standard_queue_worker(TP_CALLBACK_INSTANCE *instance, void *context, TP_WORK *work) @@ -442,6 +448,15 @@ static void CALLBACK scheduled_item_cancelable_callback(TP_CALLBACK_INSTANCE *in release_work_item(item); }
+static void CALLBACK periodic_item_callback(TP_CALLBACK_INSTANCE *instance, void *context, TP_TIMER *timer) +{ + struct work_item *item = grab_work_item(context); + + invoke_async_callback(item->result); + + release_work_item(item); +} + static void queue_mark_item_pending(DWORD mask, struct work_item *item, MFWORKITEM_KEY *key) { *key = generate_item_key(mask); @@ -478,7 +493,8 @@ static HRESULT queue_submit_wait(struct queue *queue, HANDLE event, LONG priorit return S_OK; }
-static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, INT64 timeout, MFWORKITEM_KEY *key) +static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, INT64 timeout, DWORD period, + MFWORKITEM_KEY *key) { PTP_TIMER_CALLBACK callback; struct work_item *item; @@ -491,17 +507,19 @@ static HRESULT queue_submit_timer(struct queue *queue, IMFAsyncResult *result, I if (key) { queue_mark_item_pending(SCHEDULED_ITEM_KEY_MASK, item, key); - callback = scheduled_item_cancelable_callback; } + + if (period) + callback = periodic_item_callback; else - callback = scheduled_item_callback; + callback = key ? scheduled_item_cancelable_callback : scheduled_item_callback;
t.QuadPart = timeout * 1000 * 10; filetime.dwLowDateTime = t.u.LowPart; filetime.dwHighDateTime = t.u.HighPart;
item->u.timer_object = CreateThreadpoolTimer(callback, item, &queue->env); - SetThreadpoolTimer(item->u.timer_object, &filetime, 0, 0); + SetThreadpoolTimer(item->u.timer_object, &filetime, period, 0);
TRACE("dispatched %p.\n", result);
@@ -842,7 +860,7 @@ static HRESULT schedule_work_item(IMFAsyncResult *result, INT64 timeout, MFWORKI
TRACE("%p, %s, %p.\n", result, wine_dbgstr_longlong(timeout), key);
- hr = queue_submit_timer(queue, result, timeout, key); + hr = queue_submit_timer(queue, result, timeout, 0, key);
return hr; } @@ -912,3 +930,165 @@ HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key)
return hr; } + +static DWORD get_timer_period(void) +{ + return 10; +} + +/*********************************************************************** + * MFGetTimerPeriodicity (mfplat.@) + */ +HRESULT WINAPI MFGetTimerPeriodicity(DWORD *period) +{ + TRACE("%p.\n", period); + + *period = get_timer_period(); + + return S_OK; +} + +struct periodic_callback +{ + IMFAsyncCallback IMFAsyncCallback_iface; + LONG refcount; + MFPERIODICCALLBACK callback; +}; + +static struct periodic_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) +{ + return CONTAINING_RECORD(iface, struct periodic_callback, IMFAsyncCallback_iface); +} + +static HRESULT WINAPI periodic_callback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFAsyncCallback) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFAsyncCallback_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI periodic_callback_AddRef(IMFAsyncCallback *iface) +{ + struct periodic_callback *callback = impl_from_IMFAsyncCallback(iface); + ULONG refcount = InterlockedIncrement(&callback->refcount); + + TRACE("%p, %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI periodic_callback_Release(IMFAsyncCallback *iface) +{ + struct periodic_callback *callback = impl_from_IMFAsyncCallback(iface); + ULONG refcount = InterlockedDecrement(&callback->refcount); + + TRACE("%p, %u.\n", iface, refcount); + + if (!refcount) + heap_free(callback); + + return refcount; +} + +static HRESULT WINAPI periodic_callback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI periodic_callback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +{ + struct periodic_callback *callback = impl_from_IMFAsyncCallback(iface); + IUnknown *context = NULL; + + IMFAsyncResult_GetObject(result, &context); + + callback->callback(context); + + if (context) + IUnknown_Release(context); + + return S_OK; +} + +static const IMFAsyncCallbackVtbl periodic_callback_vtbl = +{ + periodic_callback_QueryInterface, + periodic_callback_AddRef, + periodic_callback_Release, + periodic_callback_GetParameters, + periodic_callback_Invoke, +}; + +static HRESULT create_periodic_callback_obj(MFPERIODICCALLBACK callback, IMFAsyncCallback **out) +{ + struct periodic_callback *object; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + object->IMFAsyncCallback_iface.lpVtbl = &periodic_callback_vtbl; + object->refcount = 1; + object->callback = callback; + + *out = &object->IMFAsyncCallback_iface; + + return S_OK; +} + +/*********************************************************************** + * MFAddPeriodicCallback (mfplat.@) + */ +HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key) +{ + IMFAsyncCallback *periodic_callback; + MFWORKITEM_KEY workitem_key; + IMFAsyncResult *result; + struct queue *queue; + HRESULT hr; + + TRACE("%p, %p, %p.\n", callback, context, key); + + if (FAILED(hr = grab_queue(MFASYNC_CALLBACK_QUEUE_TIMER, &queue))) + return hr; + + if (FAILED(hr = create_periodic_callback_obj(callback, &periodic_callback))) + return hr; + + hr = create_async_result(context, periodic_callback, NULL, &result); + IMFAsyncCallback_Release(periodic_callback); + if (FAILED(hr)) + return hr; + + hr = queue_submit_timer(queue, result, 0, get_timer_period(), key ? &workitem_key : NULL); + + IMFAsyncResult_Release(result); + + if (key) + *key = workitem_key; + + return S_OK; +} + +/*********************************************************************** + * MFRemovePeriodicCallback (mfplat.@) + */ +HRESULT WINAPI MFRemovePeriodicCallback(DWORD key) +{ + struct queue *queue; + HRESULT hr; + + TRACE("%#x.\n", key); + + if (FAILED(hr = grab_queue(MFASYNC_CALLBACK_QUEUE_TIMER, &queue))) + return hr; + + return queue_cancel_item(queue, get_item_key(SCHEDULED_ITEM_KEY_MASK, key)); +} diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 2a2189b4d3..e413d61dfa 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -45,6 +45,8 @@ static void* (WINAPI *pMFHeapAlloc)(SIZE_T size, ULONG flags, char *file, int static void (WINAPI *pMFHeapFree)(void *p); static HRESULT (WINAPI *pMFPutWaitingWorkItem)(HANDLE event, LONG priority, IMFAsyncResult *result, MFWORKITEM_KEY *key); static HRESULT (WINAPI *pMFAllocateSerialWorkQueue)(DWORD queue, DWORD *serial_queue); +static HRESULT (WINAPI *pMFAddPeriodicCallback)(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key); +static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key);
DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
@@ -314,6 +316,7 @@ static void init_functions(void) HMODULE mod = GetModuleHandleA("mfplat.dll");
#define X(f) p##f = (void*)GetProcAddress(mod, #f) + X(MFAddPeriodicCallback); X(MFAllocateSerialWorkQueue); X(MFCopyImage); X(MFCreateSourceResolver); @@ -322,6 +325,7 @@ static void init_functions(void) X(MFHeapAlloc); X(MFHeapFree); X(MFPutWaitingWorkItem); + X(MFRemovePeriodicCallback); #undef X }
@@ -1199,6 +1203,49 @@ static void test_serial_queue(void) ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); }
+static LONG periodic_counter; +static void CALLBACK periodic_callback(IUnknown *context) +{ + InterlockedIncrement(&periodic_counter); +} + +static void test_periodic_callback(void) +{ + DWORD period, key; + HRESULT hr; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + period = 0; + hr = MFGetTimerPeriodicity(&period); + ok(hr == S_OK, "Failed to get timer perdiod, hr %#x.\n", hr); + ok(period == 10, "Unexpected period %u.\n", period); + + if (!pMFAddPeriodicCallback) + { + win_skip("Periodic callbacks are not supported.\n"); + MFShutdown(); + return; + } + + ok(periodic_counter == 0, "Unexpected counter value %u.\n", periodic_counter); + + hr = pMFAddPeriodicCallback(periodic_callback, NULL, &key); + ok(hr == S_OK, "Failed to add periodic callback, hr %#x.\n", hr); + ok(key != 0, "Unexpected key %#x.\n", key); + + Sleep(10 * period); + + hr = pMFRemovePeriodicCallback(key); + ok(hr == S_OK, "Failed to remove callback, hr %#x.\n", hr); + + ok(periodic_counter > 0, "Unexpected counter value %u.\n", periodic_counter); + + hr = MFShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); +} + START_TEST(mfplat) { CoInitialize(NULL); @@ -1222,6 +1269,7 @@ START_TEST(mfplat) test_MFHeapAlloc(); test_scheduled_items(); test_serial_queue(); + test_periodic_callback();
CoUninitialize(); } diff --git a/include/mfapi.h b/include/mfapi.h index ee5cf4c069..129a19c883 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -95,6 +95,9 @@ typedef enum MF_MULTITHREADED_WORKQUEUE, } MFASYNC_WORKQUEUE_TYPE;
+typedef void (*CALLBACK MFPERIODICCALLBACK)(IUnknown *context); + +HRESULT WINAPI MFAddPeriodicCallback(MFPERIODICCALLBACK callback, IUnknown *context, DWORD *key); HRESULT WINAPI MFAllocateWorkQueue(DWORD *queue); HRESULT WINAPI MFAllocateWorkQueueEx(MFASYNC_WORKQUEUE_TYPE queue_type, DWORD *queue); HRESULT WINAPI MFCancelWorkItem(MFWORKITEM_KEY key); @@ -131,6 +134,7 @@ HRESULT WINAPI MFTRegister(CLSID clsid, GUID category, LPWSTR name, UINT32 flags HRESULT WINAPI MFTRegisterLocal(IClassFactory *factory, REFGUID category, LPCWSTR name, UINT32 flags, UINT32 cinput, const MFT_REGISTER_TYPE_INFO *input_types, UINT32 coutput, const MFT_REGISTER_TYPE_INFO* output_types); +HRESULT WINAPI MFRemovePeriodicCallback(DWORD key); HRESULT WINAPI MFShutdown(void); HRESULT WINAPI MFStartup(ULONG version, DWORD flags); HRESULT WINAPI MFUnlockPlatform(void);
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/main.c | 18 ++++++++++++++ dlls/mf/mf.spec | 2 +- dlls/mf/tests/mf.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ include/mfidl.idl | 17 +++++++++++++ 4 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/dlls/mf/main.c b/dlls/mf/main.c index 73cd6aa3f1..b3573d78af 100644 --- a/dlls/mf/main.c +++ b/dlls/mf/main.c @@ -74,3 +74,21 @@ HRESULT WINAPI MFGetService(IUnknown *object, REFGUID service, REFIID riid, void IMFGetService_Release(gs); return hr; } + +/*********************************************************************** + * MFShutdownObject (mf.@) + */ +HRESULT WINAPI MFShutdownObject(IUnknown *object) +{ + IMFShutdown *shutdown; + + TRACE("%p.\n", object); + + if (object && SUCCEEDED(IUnknown_QueryInterface(object, &IID_IMFShutdown, (void **)&shutdown))) + { + IMFShutdown_Shutdown(shutdown); + IMFShutdown_Release(shutdown); + } + + return S_OK; +} diff --git a/dlls/mf/mf.spec b/dlls/mf/mf.spec index 64f0b1db83..7ec8e57c1f 100644 --- a/dlls/mf/mf.spec +++ b/dlls/mf/mf.spec @@ -78,6 +78,6 @@ @ stub MFGetTopoNodeCurrentType @ stub MFReadSequencerSegmentOffset @ stub MFRequireProtectedEnvironment -@ stub MFShutdownObject +@ stdcall MFShutdownObject(ptr) @ stub MFTranscodeGetAudioOutputAvailableTypes @ stub MergePropertyStore diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index ba11a27c33..915b851900 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -502,6 +502,66 @@ static void test_topology_loader(void) IMFTopoLoader_Release(loader); }
+static HRESULT WINAPI testshutdown_QueryInterface(IMFShutdown *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFShutdown) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFShutdown_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI testshutdown_AddRef(IMFShutdown *iface) +{ + return 2; +} + +static ULONG WINAPI testshutdown_Release(IMFShutdown *iface) +{ + return 1; +} + +static HRESULT WINAPI testshutdown_Shutdown(IMFShutdown *iface) +{ + return 0xdead; +} + +static HRESULT WINAPI testshutdown_GetShutdownStatus(IMFShutdown *iface, MFSHUTDOWN_STATUS *status) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static const IMFShutdownVtbl testshutdownvtbl = +{ + testshutdown_QueryInterface, + testshutdown_AddRef, + testshutdown_Release, + testshutdown_Shutdown, + testshutdown_GetShutdownStatus, +}; + +static void test_MFShutdownObject(void) +{ + IMFShutdown testshutdown = { &testshutdownvtbl }; + IUnknown testshutdown2 = { &testservicevtbl }; + HRESULT hr; + + hr = MFShutdownObject(NULL); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = MFShutdownObject((IUnknown *)&testshutdown); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + + hr = MFShutdownObject(&testshutdown2); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); +} + START_TEST(mf) { test_topology(); @@ -509,4 +569,5 @@ START_TEST(mf) test_MFGetService(); test_MFCreateSequencerSource(); test_media_session(); + test_MFShutdownObject(); } diff --git a/include/mfidl.idl b/include/mfidl.idl index 01e86efc51..be8795c854 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -329,6 +329,7 @@ cpp_quote("HRESULT WINAPI MFCreateTopoLoader(IMFTopoLoader **loader);") cpp_quote("HRESULT WINAPI MFGetSupportedMimeTypes(PROPVARIANT *array);") cpp_quote("HRESULT WINAPI MFGetService(IUnknown *object, REFGUID service, REFIID iid, void **obj);") cpp_quote("MFTIME WINAPI MFGetSystemTime(void);") +cpp_quote("HRESULT WINAPI MFShutdownObject(IUnknown *object);")
[ object, @@ -381,6 +382,22 @@ interface IMFMediaSink : IUnknown HRESULT Shutdown(); }
+typedef enum _MFSHUTDOWN_STATUS +{ + MFSHUTDOWN_INITIATED, + MFSHUTDOWN_COMPLETED, +} MFSHUTDOWN_STATUS; + +[ + object, + uuid(97ec2ea4-0e42-4937-97ac-9d6d328824e1) +] +interface IMFShutdown : IUnknown +{ + HRESULT Shutdown(); + HRESULT GetShutdownStatus([out] MFSHUTDOWN_STATUS *status); +} + cpp_quote("#define MF_RESOLUTION_MEDIASOURCE 0x00000001") cpp_quote("#define MF_RESOLUTION_BYTESTREAM 0x00000002") cpp_quote("#define MF_RESOLUTION_CONTENT_DOES_NOT_HAVE_TO_MATCH_EXTENSION_OR_MIME_TYPE 0x00000010")
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 336 ++++++++++++++++++++++++++++--------- dlls/mfplat/tests/mfplat.c | 202 +++++++++++++++++++++- include/mferror.h | 1 + include/mfobjects.idl | 2 + 4 files changed, 455 insertions(+), 86 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 0bf7cbf4c9..0ffcd88a38 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -35,6 +35,7 @@ #include "wine/heap.h" #include "wine/debug.h" #include "wine/unicode.h" +#include "wine/list.h"
#include "mfplat_private.h"
@@ -2797,6 +2798,9 @@ static const IMFMediaEventVtbl mfmediaevent_vtbl = mfmediaevent_GetValue, };
+/*********************************************************************** + * MFCreateMediaEvent (mfplat.@) + */ HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HRESULT status, const PROPVARIANT *value, IMFMediaEvent **event) { @@ -2824,141 +2828,316 @@ HRESULT WINAPI MFCreateMediaEvent(MediaEventType type, REFGUID extended_type, HR return S_OK; }
-typedef struct _mfeventqueue +struct event_queue { IMFMediaEventQueue IMFMediaEventQueue_iface; - LONG ref; -} mfeventqueue; + LONG refcount; + + CRITICAL_SECTION cs; + CONDITION_VARIABLE update_event; + struct list events; + BOOL is_shut_down; + IMFAsyncResult *subscriber; +}; + +struct queued_event +{ + struct list entry; + IMFMediaEvent *event; +};
-static inline mfeventqueue *impl_from_IMFMediaEventQueue(IMFMediaEventQueue *iface) +static inline struct event_queue *impl_from_IMFMediaEventQueue(IMFMediaEventQueue *iface) { - return CONTAINING_RECORD(iface, mfeventqueue, IMFMediaEventQueue_iface); + return CONTAINING_RECORD(iface, struct event_queue, IMFMediaEventQueue_iface); }
-static HRESULT WINAPI mfeventqueue_QueryInterface(IMFMediaEventQueue *iface, REFIID riid, void **out) +static IMFMediaEvent *queue_pop_event(struct event_queue *queue) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct list *head = list_head(&queue->events); + struct queued_event *queued_event; + IMFMediaEvent *event;
- TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out); + if (!head) + return NULL;
- if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMFMediaEventQueue)) - { - *out = &This->IMFMediaEventQueue_iface; - } - else + queued_event = LIST_ENTRY(head, struct queued_event, entry); + event = queued_event->event; + list_remove(&queued_event->entry); + heap_free(queued_event); + return event; +} + +static void event_queue_cleanup(struct event_queue *queue) +{ + IMFMediaEvent *event; + + while ((event = queue_pop_event(queue))) + IMFMediaEvent_Release(event); +} + +static HRESULT WINAPI eventqueue_QueryInterface(IMFMediaEventQueue *iface, REFIID riid, void **out) +{ + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFMediaEventQueue) || + IsEqualIID(riid, &IID_IUnknown)) { - FIXME("(%s, %p)\n", debugstr_guid(riid), out); - *out = NULL; - return E_NOINTERFACE; + *out = &queue->IMFMediaEventQueue_iface; + IMFMediaEventQueue_AddRef(iface); + return S_OK; }
- IUnknown_AddRef((IUnknown*)*out); - return S_OK; + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; }
-static ULONG WINAPI mfeventqueue_AddRef(IMFMediaEventQueue *iface) +static ULONG WINAPI eventqueue_AddRef(IMFMediaEventQueue *iface) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); - ULONG ref = InterlockedIncrement(&This->ref); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + ULONG refcount = InterlockedIncrement(&queue->refcount);
- TRACE("(%p) ref=%u\n", This, ref); + TRACE("%p, refcount %u.\n", iface, refcount);
- return ref; + return refcount; }
-static ULONG WINAPI mfeventqueue_Release(IMFMediaEventQueue *iface) +static ULONG WINAPI eventqueue_Release(IMFMediaEventQueue *iface) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); - ULONG ref = InterlockedDecrement(&This->ref); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + ULONG refcount = InterlockedDecrement(&queue->refcount);
- TRACE("(%p) ref=%u\n", This, ref); + TRACE("%p, refcount %u.\n", queue, refcount);
- if (!ref) + if (!refcount) { - HeapFree(GetProcessHeap(), 0, This); + event_queue_cleanup(queue); + DeleteCriticalSection(&queue->cs); + heap_free(queue); }
- return ref; + return refcount; }
-static HRESULT WINAPI mfeventqueue_GetEvent(IMFMediaEventQueue *iface, DWORD flags, IMFMediaEvent **event) +static HRESULT WINAPI eventqueue_GetEvent(IMFMediaEventQueue *iface, DWORD flags, IMFMediaEvent **event) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + HRESULT hr = S_OK;
- FIXME("%p, %p\n", This, event); + TRACE("%p, %p.\n", iface, event);
- return E_NOTIMPL; + EnterCriticalSection(&queue->cs); + + if (queue->is_shut_down) + hr = MF_E_SHUTDOWN; + else if (queue->subscriber) + hr = MF_E_MULTIPLE_SUBSCRIBERS; + else + { + if (flags & MF_EVENT_FLAG_NO_WAIT) + { + if (!(*event = queue_pop_event(queue))) + hr = MF_E_NO_EVENTS_AVAILABLE; + } + else + { + while (list_empty(&queue->events) && !queue->is_shut_down) + { + SleepConditionVariableCS(&queue->update_event, &queue->cs, INFINITE); + } + *event = queue_pop_event(queue); + if (queue->is_shut_down) + hr = MF_E_SHUTDOWN; + } + } + + LeaveCriticalSection(&queue->cs); + + return hr; }
-static HRESULT WINAPI mfeventqueue_BeginGetEvent(IMFMediaEventQueue *iface, IMFAsyncCallback *callback, IUnknown *state) +static void queue_notify_subscriber(struct event_queue *queue) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + if (list_empty(&queue->events) || !queue->subscriber) + return;
- FIXME("%p, %p, %p\n", This, callback, state); + MFPutWorkItemEx(MFASYNC_CALLBACK_QUEUE_STANDARD, queue->subscriber); +}
- return E_NOTIMPL; +static HRESULT WINAPI eventqueue_BeginGetEvent(IMFMediaEventQueue *iface, IMFAsyncCallback *callback, IUnknown *state) +{ + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + MFASYNCRESULT *result_data = (MFASYNCRESULT *)queue->subscriber; + HRESULT hr; + + TRACE("%p, %p, %p.\n", iface, callback, state); + + if (!callback) + return E_INVALIDARG; + + EnterCriticalSection(&queue->cs); + + if (queue->is_shut_down) + hr = MF_E_SHUTDOWN; + else if (result_data) + { + if (result_data->pCallback == callback) + hr = IMFAsyncResult_GetStateNoAddRef(queue->subscriber) == state ? + MF_S_MULTIPLE_BEGIN : MF_E_MULTIPLE_BEGIN; + else + hr = MF_E_MULTIPLE_SUBSCRIBERS; + } + else + { + hr = MFCreateAsyncResult(NULL, callback, state, &queue->subscriber); + if (SUCCEEDED(hr)) + queue_notify_subscriber(queue); + } + + LeaveCriticalSection(&queue->cs); + + return hr; }
-static HRESULT WINAPI mfeventqueue_EndGetEvent(IMFMediaEventQueue *iface, IMFAsyncResult *result, IMFMediaEvent **event) +static HRESULT WINAPI eventqueue_EndGetEvent(IMFMediaEventQueue *iface, IMFAsyncResult *result, IMFMediaEvent **event) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + HRESULT hr = E_FAIL;
- FIXME("%p, %p, %p\n", This, result, event); + TRACE("%p, %p, %p.\n", iface, result, event);
- return E_NOTIMPL; + EnterCriticalSection(&queue->cs); + + if (queue->is_shut_down) + hr = MF_E_SHUTDOWN; + else if (queue->subscriber == result) + { + *event = queue_pop_event(queue); + if (queue->subscriber) + IMFAsyncResult_Release(queue->subscriber); + queue->subscriber = NULL; + hr = *event ? S_OK : E_FAIL; + } + + LeaveCriticalSection(&queue->cs); + + return hr; }
-static HRESULT WINAPI mfeventqueue_QueueEvent(IMFMediaEventQueue *iface, IMFMediaEvent *event) +static HRESULT eventqueue_queue_event(struct event_queue *queue, IMFMediaEvent *event) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct queued_event *queued_event; + HRESULT hr = S_OK; + + queued_event = heap_alloc(sizeof(*queued_event)); + if (!queued_event) + return E_OUTOFMEMORY;
- FIXME("%p, %p\n", This, event); + queued_event->event = event;
- return E_NOTIMPL; + EnterCriticalSection(&queue->cs); + + if (queue->is_shut_down) + hr = MF_E_SHUTDOWN; + else + { + IMFMediaEvent_AddRef(queued_event->event); + list_add_tail(&queue->events, &queued_event->entry); + queue_notify_subscriber(queue); + } + + LeaveCriticalSection(&queue->cs); + + if (FAILED(hr)) + heap_free(queued_event); + + WakeAllConditionVariable(&queue->update_event); + + return hr; }
-static HRESULT WINAPI mfeventqueue_QueueEventParamVar(IMFMediaEventQueue *iface, MediaEventType met, - REFGUID type, HRESULT status, const PROPVARIANT *value) +static HRESULT WINAPI eventqueue_QueueEvent(IMFMediaEventQueue *iface, IMFMediaEvent *event) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface);
- FIXME("%p, %d, %s, 0x%08x, %p\n", This, met, debugstr_guid(type), status, value); + TRACE("%p, %p.\n", iface, event);
- return E_NOTIMPL; + return eventqueue_queue_event(queue, event); }
-static HRESULT WINAPI mfeventqueue_QueueEventParamUnk(IMFMediaEventQueue *iface, MediaEventType met, REFGUID type, - HRESULT status, IUnknown *unk) +static HRESULT WINAPI eventqueue_QueueEventParamVar(IMFMediaEventQueue *iface, MediaEventType event_type, + REFGUID extended_type, HRESULT status, const PROPVARIANT *value) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + IMFMediaEvent *event; + HRESULT hr;
- FIXME("%p, %d, %s, 0x%08x, %p\n", This, met, debugstr_guid(type), status, unk); + TRACE("%p, %d, %s, %#x, %p\n", iface, event_type, debugstr_guid(extended_type), status, value);
- return E_NOTIMPL; + if (FAILED(hr = MFCreateMediaEvent(event_type, extended_type, status, value, &event))) + return hr; + + hr = eventqueue_queue_event(queue, event); + IMFMediaEvent_Release(event); + return hr; }
-static HRESULT WINAPI mfeventqueue_Shutdown(IMFMediaEventQueue *iface) +static HRESULT WINAPI eventqueue_QueueEventParamUnk(IMFMediaEventQueue *iface, MediaEventType event_type, + REFGUID extended_type, HRESULT status, IUnknown *unk) { - mfeventqueue *This = impl_from_IMFMediaEventQueue(iface); + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + IMFMediaEvent *event; + PROPVARIANT value; + HRESULT hr;
- FIXME("%p\n", This); + TRACE("%p, %d, %s, %#x, %p.\n", iface, event_type, debugstr_guid(extended_type), status, unk);
- return E_NOTIMPL; + value.vt = VT_UNKNOWN; + value.punkVal = unk; + + if (FAILED(hr = MFCreateMediaEvent(event_type, extended_type, status, &value, &event))) + return hr; + + hr = eventqueue_queue_event(queue, event); + IMFMediaEvent_Release(event); + return hr; }
-static const IMFMediaEventQueueVtbl mfeventqueue_vtbl = +static HRESULT WINAPI eventqueue_Shutdown(IMFMediaEventQueue *iface) { - mfeventqueue_QueryInterface, - mfeventqueue_AddRef, - mfeventqueue_Release, - mfeventqueue_GetEvent, - mfeventqueue_BeginGetEvent, - mfeventqueue_EndGetEvent, - mfeventqueue_QueueEvent, - mfeventqueue_QueueEventParamVar, - mfeventqueue_QueueEventParamUnk, - mfeventqueue_Shutdown + struct event_queue *queue = impl_from_IMFMediaEventQueue(iface); + + TRACE("%p\n", queue); + + EnterCriticalSection(&queue->cs); + + if (!queue->is_shut_down) + { + event_queue_cleanup(queue); + queue->is_shut_down = TRUE; + } + + LeaveCriticalSection(&queue->cs); + + WakeAllConditionVariable(&queue->update_event); + + return S_OK; +} + +static const IMFMediaEventQueueVtbl eventqueuevtbl = +{ + eventqueue_QueryInterface, + eventqueue_AddRef, + eventqueue_Release, + eventqueue_GetEvent, + eventqueue_BeginGetEvent, + eventqueue_EndGetEvent, + eventqueue_QueueEvent, + eventqueue_QueueEventParamVar, + eventqueue_QueueEventParamUnk, + eventqueue_Shutdown };
/*********************************************************************** @@ -2966,16 +3145,19 @@ static const IMFMediaEventQueueVtbl mfeventqueue_vtbl = */ HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue) { - mfeventqueue *object; + struct event_queue *object;
TRACE("%p\n", queue);
- object = HeapAlloc( GetProcessHeap(), 0, sizeof(*object) ); - if(!object) + object = heap_alloc_zero(sizeof(*object)); + if (!object) return E_OUTOFMEMORY;
- object->ref = 1; - object->IMFMediaEventQueue_iface.lpVtbl = &mfeventqueue_vtbl; + object->IMFMediaEventQueue_iface.lpVtbl = &eventqueuevtbl; + object->refcount = 1; + list_init(&object->events); + InitializeCriticalSection(&object->cs); + InitializeConditionVariable(&object->update_event);
*queue = &object->IMFMediaEventQueue_iface;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index e413d61dfa..4405bd9282 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -36,6 +36,8 @@
#include "wine/test.h"
+static BOOL is_win8_plus; + static HRESULT (WINAPI *pMFCopyImage)(BYTE *dest, LONG deststride, const BYTE *src, LONG srcstride, DWORD width, DWORD lines); static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver); @@ -327,6 +329,8 @@ static void init_functions(void) X(MFPutWaitingWorkItem); X(MFRemovePeriodicCallback); #undef X + + is_win8_plus = pMFPutWaitingWorkItem != NULL; }
static void test_MFCreateMediaType(void) @@ -700,6 +704,17 @@ static void test_MFSample(void) IMFSample_Release(sample); }
+struct test_callback +{ + IMFAsyncCallback IMFAsyncCallback_iface; + HANDLE event; +}; + +static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) +{ + return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface); +} + static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMFAsyncCallback) || @@ -732,7 +747,43 @@ static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD
static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) { + struct test_callback *callback = impl_from_IMFAsyncCallback(iface); + IMFMediaEventQueue *queue; + IUnknown *state, *obj; + HRESULT hr; + ok(result != NULL, "Unexpected result object.\n"); + + state = IMFAsyncResult_GetStateNoAddRef(result); + if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaEventQueue, (void **)&queue))) + { + IMFMediaEvent *event; + + if (is_win8_plus) + { + hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr); + + hr = IMFMediaEventQueue_GetEvent(queue, 0, &event); + ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Failed to get event, hr %#x.\n", hr); + } + + hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event); + ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr); + + hr = IMFAsyncResult_GetObject(result, &obj); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + IMFMediaEvent_Release(event); + + hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event); + ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr); + + IMFMediaEventQueue_Release(queue); + + SetEvent(callback->event); + } + return E_NOTIMPL; }
@@ -745,15 +796,23 @@ static const IMFAsyncCallbackVtbl testcallbackvtbl = testcallback_Invoke, };
+static void init_test_callback(struct test_callback *callback) +{ + callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl; + callback->event = NULL; +} + static void test_MFCreateAsyncResult(void) { - IMFAsyncCallback callback = { &testcallbackvtbl }; IMFAsyncResult *result, *result2; + struct test_callback callback; IUnknown *state, *object; MFASYNCRESULT *data; ULONG refcount; HRESULT hr;
+ init_test_callback(&callback); + hr = MFCreateAsyncResult(NULL, NULL, NULL, NULL); ok(FAILED(hr), "Unexpected hr %#x.\n", hr);
@@ -797,11 +856,11 @@ static void test_MFCreateAsyncResult(void) ok(state == NULL, "Unexpected state.\n");
/* Object. */ - hr = MFCreateAsyncResult((IUnknown *)result, &callback, NULL, &result2); + hr = MFCreateAsyncResult((IUnknown *)result, &callback.IMFAsyncCallback_iface, NULL, &result2); ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
data = (MFASYNCRESULT *)result2; - ok(data->pCallback == &callback, "Unexpected callback value.\n"); + ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n"); ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult); ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred); ok(data->hEvent == NULL, "Unexpected event.\n"); @@ -815,11 +874,11 @@ static void test_MFCreateAsyncResult(void) IMFAsyncResult_Release(result2);
/* State object. */ - hr = MFCreateAsyncResult(NULL, &callback, (IUnknown *)result, &result2); + hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, (IUnknown *)result, &result2); ok(hr == S_OK, "Failed to create object, hr %#x.\n", hr);
data = (MFASYNCRESULT *)result2; - ok(data->pCallback == &callback, "Unexpected callback value.\n"); + ok(data->pCallback == &callback.IMFAsyncCallback_iface, "Unexpected callback value.\n"); ok(data->hrStatusResult == S_OK, "Unexpected status %#x.\n", data->hrStatusResult); ok(data->dwBytesTransferred == 0, "Unexpected byte length %u.\n", data->dwBytesTransferred); ok(data->hEvent == NULL, "Unexpected event.\n"); @@ -1096,15 +1155,17 @@ static void test_MFHeapAlloc(void)
static void test_scheduled_items(void) { - IMFAsyncCallback callback = { &testcallbackvtbl }; + struct test_callback callback; IMFAsyncResult *result; MFWORKITEM_KEY key, key2; HRESULT hr;
+ init_test_callback(&callback); + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr);
- hr = MFScheduleWorkItem(&callback, NULL, -5000, &key); + hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key); ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
hr = MFCancelWorkItem(key); @@ -1119,7 +1180,7 @@ static void test_scheduled_items(void) return; }
- hr = MFCreateAsyncResult(NULL, &callback, NULL, &result); + hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result); ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr);
hr = pMFPutWaitingWorkItem(NULL, 0, result, &key); @@ -1136,7 +1197,7 @@ static void test_scheduled_items(void)
IMFAsyncResult_Release(result);
- hr = MFScheduleWorkItem(&callback, NULL, -5000, &key); + hr = MFScheduleWorkItem(&callback.IMFAsyncCallback_iface, NULL, -5000, &key); ok(hr == S_OK, "Failed to schedule item, hr %#x.\n", hr);
hr = MFCancelWorkItem(key); @@ -1246,6 +1307,128 @@ static void test_periodic_callback(void) ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); }
+static void test_event_queue(void) +{ + struct test_callback callback, callback2; + IMFMediaEvent *event, *event2; + IMFMediaEventQueue *queue; + IMFAsyncResult *result; + HRESULT hr; + DWORD ret; + + init_test_callback(&callback); + init_test_callback(&callback2); + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#x.\n", hr); + + hr = MFCreateEventQueue(&queue); + ok(hr == S_OK, "Failed to create event queue, hr %#x.\n", hr); + + hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr); + + hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event); + ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr); + + if (is_win8_plus) + { + hr = IMFMediaEventQueue_QueueEvent(queue, event); + ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr); + + hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + ok(event2 == event, "Unexpected event object.\n"); + IMFMediaEvent_Release(event2); + + hr = IMFMediaEventQueue_QueueEvent(queue, event); + ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr); + + hr = IMFMediaEventQueue_GetEvent(queue, 0, &event2); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + IMFMediaEvent_Release(event2); + } + + /* Async case. */ + hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue); + ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr); + + /* Same callback, same state. */ + hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)queue); + ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr); + + /* Same callback, different state. */ + hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback); + ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr); + + /* Different callback, same state. */ + hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)queue); + ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr); + + /* Different callback, different state. */ + hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface); + ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr); + + callback.event = CreateEventA(NULL, FALSE, FALSE, NULL); + + hr = IMFMediaEventQueue_QueueEvent(queue, event); + ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr); + + ret = WaitForSingleObject(callback.event, 100); + ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret); + + CloseHandle(callback.event); + + IMFMediaEvent_Release(event); + + hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result); + ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr); + + hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + /* Shutdown behavior. */ + hr = IMFMediaEventQueue_Shutdown(queue); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + + hr = IMFMediaEventQueue_GetEvent(queue, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = MFCreateMediaEvent(MEError, &GUID_NULL, E_FAIL, NULL, &event); + ok(hr == S_OK, "Failed to create event object, hr %#x.\n", hr); + hr = IMFMediaEventQueue_QueueEvent(queue, event); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + IMFMediaEvent_Release(event); + + hr = IMFMediaEventQueue_QueueEventParamUnk(queue, MEError, &GUID_NULL, E_FAIL, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEventQueue_QueueEventParamVar(queue, MEError, &GUID_NULL, E_FAIL, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEventQueue_BeginGetEvent(queue, &callback.IMFAsyncCallback_iface, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEventQueue_BeginGetEvent(queue, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaEventQueue_EndGetEvent(queue, result, &event); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + IMFAsyncResult_Release(result); + + /* Already shut down. */ + hr = IMFMediaEventQueue_Shutdown(queue); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + + IMFMediaEventQueue_Release(queue); + + hr = MFShutdown(); + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); +} + START_TEST(mfplat) { CoInitialize(NULL); @@ -1270,6 +1453,7 @@ START_TEST(mfplat) test_scheduled_items(); test_serial_queue(); test_periodic_callback(); + test_event_queue();
CoUninitialize(); } diff --git a/include/mferror.h b/include/mferror.h index 53024caed1..54f09fefdc 100644 --- a/include/mferror.h +++ b/include/mferror.h @@ -66,6 +66,7 @@ #define MF_E_ATTRIBUTENOTFOUND _HRESULT_TYPEDEF_(0xc00d36e6) #define MF_E_PROPERTY_TYPE_NOT_ALLOWED _HRESULT_TYPEDEF_(0xc00d36e7) #define MF_E_INVALID_WORKQUEUE _HRESULT_TYPEDEF_(0xc00d36ff) +#define MF_E_NO_EVENTS_AVAILABLE _HRESULT_TYPEDEF_(0xc00d3e80) #define MF_E_SHUTDOWN _HRESULT_TYPEDEF_(0xc00d3e85)
#define MF_E_TOPO_INVALID_OPTIONAL_NODE _HRESULT_TYPEDEF_(0xc00d520e) diff --git a/include/mfobjects.idl b/include/mfobjects.idl index 3245d84d1b..b67aec2a61 100644 --- a/include/mfobjects.idl +++ b/include/mfobjects.idl @@ -553,6 +553,8 @@ interface IMFMediaEvent : IMFAttributes HRESULT GetValue([out] PROPVARIANT *pvValue); }
+cpp_quote("#define MF_EVENT_FLAG_NO_WAIT 0x00000001") + [ object, uuid(2cd0bd52-bcd5-4b89-b62c-eadc0c031e7d)
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/session.c | 4 ++ dlls/mf/tests/mf.c | 173 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 177 insertions(+)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index fda3ec7455..b576a0f184 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -171,8 +171,12 @@ static HRESULT WINAPI mfsession_Close(IMFMediaSession *iface)
static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) { + struct media_session *session = impl_from_IMFMediaSession(iface); + FIXME("(%p)\n", iface);
+ IMFMediaEventQueue_Shutdown(session->event_queue); + return E_NOTIMPL; }
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 915b851900..2d005547b7 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -33,6 +33,8 @@
#include "wine/test.h"
+DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); + static void test_topology(void) { IMFCollection *collection, *collection2; @@ -467,6 +469,175 @@ static void test_MFCreateSequencerSource(void) ok(hr == S_OK, "Shutdown failure, hr %#x.\n", hr); }
+struct test_callback +{ + IMFAsyncCallback IMFAsyncCallback_iface; + HANDLE event; +}; + +static struct test_callback *impl_from_IMFAsyncCallback(IMFAsyncCallback *iface) +{ + return CONTAINING_RECORD(iface, struct test_callback, IMFAsyncCallback_iface); +} + +static HRESULT WINAPI testcallback_QueryInterface(IMFAsyncCallback *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IMFAsyncCallback) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFAsyncCallback_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI testcallback_AddRef(IMFAsyncCallback *iface) +{ + return 2; +} + +static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface) +{ + return 1; +} + +static HRESULT WINAPI testcallback_GetParameters(IMFAsyncCallback *iface, DWORD *flags, DWORD *queue) +{ + ok(flags != NULL && queue != NULL, "Unexpected arguments.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResult *result) +{ + struct test_callback *callback = impl_from_IMFAsyncCallback(iface); + IMFMediaSession *session; + IUnknown *state, *obj; + HRESULT hr; + + ok(result != NULL, "Unexpected result object.\n"); + + state = IMFAsyncResult_GetStateNoAddRef(result); + if (state && SUCCEEDED(IUnknown_QueryInterface(state, &IID_IMFMediaSession, (void **)&session))) + { + IMFMediaEvent *event; + + hr = IMFMediaSession_EndGetEvent(session, result, &event); + ok(hr == S_OK, "Failed to finalize GetEvent, hr %#x.\n", hr); + + hr = IMFAsyncResult_GetObject(result, &obj); + ok(hr == E_POINTER, "Unexpected hr %#x.\n", hr); + + IMFMediaEvent_Release(event); + + hr = IMFMediaSession_EndGetEvent(session, result, &event); + ok(hr == E_FAIL, "Unexpected result, hr %#x.\n", hr); + + IMFMediaSession_Release(session); + + SetEvent(callback->event); + } + + return E_NOTIMPL; +} + +static const IMFAsyncCallbackVtbl testcallbackvtbl = +{ + testcallback_QueryInterface, + testcallback_AddRef, + testcallback_Release, + testcallback_GetParameters, + testcallback_Invoke, +}; + +static void init_test_callback(struct test_callback *callback) +{ + callback->IMFAsyncCallback_iface.lpVtbl = &testcallbackvtbl; + callback->event = NULL; +} + +static void test_session_events(IMFMediaSession *session) +{ + struct test_callback callback, callback2; + IMFAsyncResult *result; + IMFMediaEvent *event; + HRESULT hr; + DWORD ret; + + init_test_callback(&callback); + init_test_callback(&callback2); + + hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_NO_EVENTS_AVAILABLE, "Unexpected hr %#x.\n", hr); + + /* Async case. */ + hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session); + ok(hr == S_OK, "Failed to Begin*, hr %#x.\n", hr); + + /* Same callback, same state. */ + hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)session); + ok(hr == MF_S_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr); + + /* Same callback, different state. */ + hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, (IUnknown *)&callback); + ok(hr == MF_E_MULTIPLE_BEGIN, "Unexpected hr %#x.\n", hr); + + /* Different callback, same state. */ + hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)session); + ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr); + + /* Different callback, different state. */ + hr = IMFMediaSession_BeginGetEvent(session, &callback2.IMFAsyncCallback_iface, (IUnknown *)&callback.IMFAsyncCallback_iface); + ok(hr == MF_E_MULTIPLE_SUBSCRIBERS, "Unexpected hr %#x.\n", hr); + + callback.event = CreateEventA(NULL, FALSE, FALSE, NULL); + + hr = IMFMediaSession_QueueEvent(session, MEError, &GUID_NULL, E_FAIL, NULL); + ok(hr == S_OK, "Failed to queue event, hr %#x.\n", hr); + + ret = WaitForSingleObject(callback.event, 100); + ok(ret == WAIT_OBJECT_0, "Unexpected return value %#x.\n", ret); + + CloseHandle(callback.event); + + hr = MFCreateAsyncResult(NULL, &callback.IMFAsyncCallback_iface, NULL, &result); + ok(hr == S_OK, "Failed to create result, hr %#x.\n", hr); + + hr = IMFMediaSession_EndGetEvent(session, result, &event); + ok(hr == E_FAIL, "Unexpected hr %#x.\n", hr); + + /* Shutdown behavior. */ + hr = IMFMediaSession_Shutdown(session); +todo_wine + ok(hr == S_OK, "Failed to shut down, hr %#x.\n", hr); + + hr = IMFMediaSession_GetEvent(session, MF_EVENT_FLAG_NO_WAIT, &event); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaSession_QueueEvent(session, MEError, &GUID_NULL, E_FAIL, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaSession_BeginGetEvent(session, &callback.IMFAsyncCallback_iface, NULL); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaSession_BeginGetEvent(session, NULL, NULL); + ok(hr == E_INVALIDARG, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaSession_EndGetEvent(session, result, &event); + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); + IMFAsyncResult_Release(result); + + /* Already shut down. */ + hr = IMFMediaSession_Shutdown(session); +todo_wine + ok(hr == MF_E_SHUTDOWN, "Unexpected hr %#x.\n", hr); +} + static void test_media_session(void) { IMFMediaSession *session; @@ -482,6 +653,8 @@ static void test_media_session(void) hr = IMFMediaSession_QueryInterface(session, &IID_IMFAttributes, (void **)&unk); ok(hr == E_NOINTERFACE, "Unexpected hr %#x.\n", hr);
+ test_session_events(session); + IMFMediaSession_Release(session);
hr = MFShutdown();
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/Makefile.in | 1 + dlls/mfplat/main.c | 366 +---------------------------------- dlls/mfplat/mediatype.c | 366 +++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat_private.h | 10 + dlls/mfplat/queue.c | 1 - 5 files changed, 378 insertions(+), 366 deletions(-) create mode 100644 dlls/mfplat/mediatype.c
diff --git a/dlls/mfplat/Makefile.in b/dlls/mfplat/Makefile.in index 17cda8856c..261c121cab 100644 --- a/dlls/mfplat/Makefile.in +++ b/dlls/mfplat/Makefile.in @@ -4,4 +4,5 @@ IMPORTS = advapi32 ole32
C_SRCS = \ main.c \ + mediatype.c \ queue.c diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 0ffcd88a38..7d90c69418 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -28,7 +28,6 @@ #include "winreg.h"
#include "initguid.h" -#include "mfapi.h" #include "mfidl.h" #include "mferror.h"
@@ -544,12 +543,6 @@ HRESULT WINAPI MFCopyImage(BYTE *dest, LONG deststride, const BYTE *src, LONG sr return S_OK; }
-typedef struct _mfattributes -{ - IMFAttributes IMFAttributes_iface; - LONG ref; -} mfattributes; - static inline mfattributes *impl_from_IMFAttributes(IMFAttributes *iface) { return CONTAINING_RECORD(iface, mfattributes, IMFAttributes_iface); @@ -916,7 +909,7 @@ static const IMFAttributesVtbl mfattributes_vtbl = mfattributes_CopyAllItems };
-static void init_attribute_object(mfattributes *object, UINT32 size) +void init_attribute_object(mfattributes *object, UINT32 size) { object->ref = 1; object->IMFAttributes_iface.lpVtbl = &mfattributes_vtbl; @@ -2107,363 +2100,6 @@ HRESULT WINAPI MFCreateSourceResolver(IMFSourceResolver **resolver) return S_OK; }
-typedef struct _mfmediatype -{ - mfattributes attributes; - IMFMediaType IMFMediaType_iface; -} mfmediatype; - -static inline mfmediatype *impl_from_IMFMediaType(IMFMediaType *iface) -{ - return CONTAINING_RECORD(iface, mfmediatype, IMFMediaType_iface); -} - -static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **object) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), object); - - if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMFAttributes) || - IsEqualGUID(riid, &IID_IMFMediaType)) - { - *object = &This->IMFMediaType_iface; - } - else - { - FIXME("(%s, %p)\n", debugstr_guid(riid), object); - *object = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*object); - return S_OK; -} - -static ULONG WINAPI mediatype_AddRef(IMFMediaType *iface) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - ULONG ref = InterlockedIncrement(&This->attributes.ref); - - TRACE("(%p) ref=%u\n", This, ref); - - return ref; -} - -static ULONG WINAPI mediatype_Release(IMFMediaType *iface) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - ULONG ref = InterlockedDecrement(&This->attributes.ref); - - TRACE("(%p) ref=%u\n", This, ref); - - if (!ref) - { - HeapFree(GetProcessHeap(), 0, This); - } - - return ref; -} - -static HRESULT WINAPI mediatype_GetItem(IMFMediaType *iface, REFGUID key, PROPVARIANT *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetItem(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_GetItemType(IMFMediaType *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetItemType(&This->attributes.IMFAttributes_iface, key, type); -} - -static HRESULT WINAPI mediatype_CompareItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value, BOOL *result) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_CompareItem(&This->attributes.IMFAttributes_iface, key, value, result); -} - -static HRESULT WINAPI mediatype_Compare(IMFMediaType *iface, IMFAttributes *attrs, MF_ATTRIBUTES_MATCH_TYPE type, - BOOL *result) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_Compare(&This->attributes.IMFAttributes_iface, attrs, type, result); -} - -static HRESULT WINAPI mediatype_GetUINT32(IMFMediaType *iface, REFGUID key, UINT32 *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetUINT32(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_GetUINT64(IMFMediaType *iface, REFGUID key, UINT64 *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetUINT64(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_GetDouble(IMFMediaType *iface, REFGUID key, double *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetDouble(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_GetGUID(IMFMediaType *iface, REFGUID key, GUID *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetGUID(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_GetStringLength(IMFMediaType *iface, REFGUID key, UINT32 *length) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetStringLength(&This->attributes.IMFAttributes_iface, key, length); -} - -static HRESULT WINAPI mediatype_GetString(IMFMediaType *iface, REFGUID key, WCHAR *value, - UINT32 size, UINT32 *length) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetString(&This->attributes.IMFAttributes_iface, key, value, size, length); -} - -static HRESULT WINAPI mediatype_GetAllocatedString(IMFMediaType *iface, REFGUID key, - WCHAR **value, UINT32 *length) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetAllocatedString(&This->attributes.IMFAttributes_iface, key, value, length); -} - -static HRESULT WINAPI mediatype_GetBlobSize(IMFMediaType *iface, REFGUID key, UINT32 *size) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetBlobSize(&This->attributes.IMFAttributes_iface, key, size); -} - -static HRESULT WINAPI mediatype_GetBlob(IMFMediaType *iface, REFGUID key, UINT8 *buf, - UINT32 bufsize, UINT32 *blobsize) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetBlob(&This->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); -} - -static HRESULT WINAPI mediatype_GetAllocatedBlob(IMFMediaType *iface, REFGUID key, UINT8 **buf, UINT32 *size) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetAllocatedBlob(&This->attributes.IMFAttributes_iface, key, buf, size); -} - -static HRESULT WINAPI mediatype_GetUnknown(IMFMediaType *iface, REFGUID key, REFIID riid, void **ppv) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetUnknown(&This->attributes.IMFAttributes_iface, key, riid, ppv); -} - -static HRESULT WINAPI mediatype_SetItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetItem(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_DeleteItem(IMFMediaType *iface, REFGUID key) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_DeleteItem(&This->attributes.IMFAttributes_iface, key); -} - -static HRESULT WINAPI mediatype_DeleteAllItems(IMFMediaType *iface) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_DeleteAllItems(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mediatype_SetUINT32(IMFMediaType *iface, REFGUID key, UINT32 value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetUINT32(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_SetUINT64(IMFMediaType *iface, REFGUID key, UINT64 value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetUINT64(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_SetDouble(IMFMediaType *iface, REFGUID key, double value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetDouble(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_SetGUID(IMFMediaType *iface, REFGUID key, REFGUID value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetGUID(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_SetString(IMFMediaType *iface, REFGUID key, const WCHAR *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetString(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mediatype_SetBlob(IMFMediaType *iface, REFGUID key, const UINT8 *buf, UINT32 size) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetBlob(&This->attributes.IMFAttributes_iface, key, buf, size); -} - -static HRESULT WINAPI mediatype_SetUnknown(IMFMediaType *iface, REFGUID key, IUnknown *unknown) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_SetUnknown(&This->attributes.IMFAttributes_iface, key, unknown); -} - -static HRESULT WINAPI mediatype_LockStore(IMFMediaType *iface) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_LockStore(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mediatype_UnlockStore(IMFMediaType *iface) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_UnlockStore(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mediatype_GetCount(IMFMediaType *iface, UINT32 *items) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetCount(&This->attributes.IMFAttributes_iface, items); -} - -static HRESULT WINAPI mediatype_GetItemByIndex(IMFMediaType *iface, UINT32 index, GUID *key, PROPVARIANT *value) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - return IMFAttributes_GetItemByIndex(&This->attributes.IMFAttributes_iface, index, key, value); -} - -static HRESULT WINAPI mediatype_CopyAllItems(IMFMediaType *iface, IMFAttributes *dest) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - FIXME("%p, %p\n", This, dest); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mediatype_GetMajorType(IMFMediaType *iface, GUID *guid) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - FIXME("%p, %p\n", This, guid); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mediatype_IsCompressedFormat(IMFMediaType *iface, BOOL *compressed) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - FIXME("%p, %p\n", This, compressed); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mediatype_IsEqual(IMFMediaType *iface, IMFMediaType *type, DWORD *flags) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - FIXME("%p, %p, %p\n", This, type, flags); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mediatype_GetRepresentation(IMFMediaType *iface, GUID guid, void **representation) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - FIXME("%p, %s, %p\n", This, debugstr_guid(&guid), representation); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mediatype_FreeRepresentation(IMFMediaType *iface, GUID guid, void *representation) -{ - mfmediatype *This = impl_from_IMFMediaType(iface); - - FIXME("%p, %s, %p\n", This, debugstr_guid(&guid), representation); - - return E_NOTIMPL; -} - -static const IMFMediaTypeVtbl mediatype_vtbl = -{ - mediatype_QueryInterface, - mediatype_AddRef, - mediatype_Release, - mediatype_GetItem, - mediatype_GetItemType, - mediatype_CompareItem, - mediatype_Compare, - mediatype_GetUINT32, - mediatype_GetUINT64, - mediatype_GetDouble, - mediatype_GetGUID, - mediatype_GetStringLength, - mediatype_GetString, - mediatype_GetAllocatedString, - mediatype_GetBlobSize, - mediatype_GetBlob, - mediatype_GetAllocatedBlob, - mediatype_GetUnknown, - mediatype_SetItem, - mediatype_DeleteItem, - mediatype_DeleteAllItems, - mediatype_SetUINT32, - mediatype_SetUINT64, - mediatype_SetDouble, - mediatype_SetGUID, - mediatype_SetString, - mediatype_SetBlob, - mediatype_SetUnknown, - mediatype_LockStore, - mediatype_UnlockStore, - mediatype_GetCount, - mediatype_GetItemByIndex, - mediatype_CopyAllItems, - mediatype_GetMajorType, - mediatype_IsCompressedFormat, - mediatype_IsEqual, - mediatype_GetRepresentation, - mediatype_FreeRepresentation -}; - -/*********************************************************************** - * MFCreateMediaType (mfplat.@) - */ -HRESULT WINAPI MFCreateMediaType(IMFMediaType **type) -{ - mfmediatype *object; - - TRACE("%p\n", type); - - if(!type) - return E_INVALIDARG; - - object = heap_alloc( sizeof(*object) ); - if(!object) - return E_OUTOFMEMORY; - - init_attribute_object(&object->attributes, 0); - object->IMFMediaType_iface.lpVtbl = &mediatype_vtbl; - - *type = &object->IMFMediaType_iface; - - return S_OK; -} - typedef struct _mfmediaevent { mfattributes attributes; diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c new file mode 100644 index 0000000000..b3292a61fe --- /dev/null +++ b/dlls/mfplat/mediatype.c @@ -0,0 +1,366 @@ +/* + * Copyright 2017 Alistair Leslie-Hughes + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#define COBJMACROS + +#include "mfplat_private.h" + +#include "wine/debug.h" +#include "wine/heap.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + +struct media_type +{ + struct attributes attributes; + IMFMediaType IMFMediaType_iface; +}; + +static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface) +{ + return CONTAINING_RECORD(iface, struct media_type, IMFMediaType_iface); +} + +static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFMediaType) || + IsEqualIID(riid, &IID_IMFAttributes) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFMediaType_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI mediatype_AddRef(IMFMediaType *iface) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + ULONG refcount = InterlockedIncrement(&media_type->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI mediatype_Release(IMFMediaType *iface) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + ULONG refcount = InterlockedDecrement(&media_type->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(media_type); + } + + return refcount; +} + +static HRESULT WINAPI mediatype_GetItem(IMFMediaType *iface, REFGUID key, PROPVARIANT *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetItem(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_GetItemType(IMFMediaType *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetItemType(&media_type->attributes.IMFAttributes_iface, key, type); +} + +static HRESULT WINAPI mediatype_CompareItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value, BOOL *result) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_CompareItem(&media_type->attributes.IMFAttributes_iface, key, value, result); +} + +static HRESULT WINAPI mediatype_Compare(IMFMediaType *iface, IMFAttributes *attrs, MF_ATTRIBUTES_MATCH_TYPE type, + BOOL *result) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_Compare(&media_type->attributes.IMFAttributes_iface, attrs, type, result); +} + +static HRESULT WINAPI mediatype_GetUINT32(IMFMediaType *iface, REFGUID key, UINT32 *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetUINT32(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_GetUINT64(IMFMediaType *iface, REFGUID key, UINT64 *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetUINT64(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_GetDouble(IMFMediaType *iface, REFGUID key, double *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetDouble(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_GetGUID(IMFMediaType *iface, REFGUID key, GUID *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetGUID(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_GetStringLength(IMFMediaType *iface, REFGUID key, UINT32 *length) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetStringLength(&media_type->attributes.IMFAttributes_iface, key, length); +} + +static HRESULT WINAPI mediatype_GetString(IMFMediaType *iface, REFGUID key, WCHAR *value, + UINT32 size, UINT32 *length) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetString(&media_type->attributes.IMFAttributes_iface, key, value, size, length); +} + +static HRESULT WINAPI mediatype_GetAllocatedString(IMFMediaType *iface, REFGUID key, + WCHAR **value, UINT32 *length) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetAllocatedString(&media_type->attributes.IMFAttributes_iface, key, value, length); +} + +static HRESULT WINAPI mediatype_GetBlobSize(IMFMediaType *iface, REFGUID key, UINT32 *size) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetBlobSize(&media_type->attributes.IMFAttributes_iface, key, size); +} + +static HRESULT WINAPI mediatype_GetBlob(IMFMediaType *iface, REFGUID key, UINT8 *buf, + UINT32 bufsize, UINT32 *blobsize) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetBlob(&media_type->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); +} + +static HRESULT WINAPI mediatype_GetAllocatedBlob(IMFMediaType *iface, REFGUID key, UINT8 **buf, UINT32 *size) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetAllocatedBlob(&media_type->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI mediatype_GetUnknown(IMFMediaType *iface, REFGUID key, REFIID riid, void **ppv) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetUnknown(&media_type->attributes.IMFAttributes_iface, key, riid, ppv); +} + +static HRESULT WINAPI mediatype_SetItem(IMFMediaType *iface, REFGUID key, REFPROPVARIANT value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetItem(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_DeleteItem(IMFMediaType *iface, REFGUID key) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_DeleteItem(&media_type->attributes.IMFAttributes_iface, key); +} + +static HRESULT WINAPI mediatype_DeleteAllItems(IMFMediaType *iface) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_DeleteAllItems(&media_type->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI mediatype_SetUINT32(IMFMediaType *iface, REFGUID key, UINT32 value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetUINT32(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_SetUINT64(IMFMediaType *iface, REFGUID key, UINT64 value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetUINT64(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_SetDouble(IMFMediaType *iface, REFGUID key, double value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetDouble(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_SetGUID(IMFMediaType *iface, REFGUID key, REFGUID value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetGUID(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_SetString(IMFMediaType *iface, REFGUID key, const WCHAR *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetString(&media_type->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mediatype_SetBlob(IMFMediaType *iface, REFGUID key, const UINT8 *buf, UINT32 size) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetBlob(&media_type->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI mediatype_SetUnknown(IMFMediaType *iface, REFGUID key, IUnknown *unknown) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_SetUnknown(&media_type->attributes.IMFAttributes_iface, key, unknown); +} + +static HRESULT WINAPI mediatype_LockStore(IMFMediaType *iface) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_LockStore(&media_type->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI mediatype_UnlockStore(IMFMediaType *iface) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_UnlockStore(&media_type->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI mediatype_GetCount(IMFMediaType *iface, UINT32 *items) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetCount(&media_type->attributes.IMFAttributes_iface, items); +} + +static HRESULT WINAPI mediatype_GetItemByIndex(IMFMediaType *iface, UINT32 index, GUID *key, PROPVARIANT *value) +{ + struct media_type *media_type = impl_from_IMFMediaType(iface); + return IMFAttributes_GetItemByIndex(&media_type->attributes.IMFAttributes_iface, index, key, value); +} + +static HRESULT WINAPI mediatype_CopyAllItems(IMFMediaType *iface, IMFAttributes *dest) +{ + FIXME("%p, %p.\n", iface, dest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_GetMajorType(IMFMediaType *iface, GUID *guid) +{ + FIXME("%p, %p.\n", iface, guid); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_IsCompressedFormat(IMFMediaType *iface, BOOL *compressed) +{ + FIXME("%p, %p.\n", iface, compressed); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_IsEqual(IMFMediaType *iface, IMFMediaType *type, DWORD *flags) +{ + FIXME("%p, %p, %p.\n", iface, type, flags); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_GetRepresentation(IMFMediaType *iface, GUID guid, void **representation) +{ + FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_FreeRepresentation(IMFMediaType *iface, GUID guid, void *representation) +{ + FIXME("%p, %s, %p.\n", iface, debugstr_guid(&guid), representation); + + return E_NOTIMPL; +} + +static const IMFMediaTypeVtbl mediatypevtbl = +{ + mediatype_QueryInterface, + mediatype_AddRef, + mediatype_Release, + mediatype_GetItem, + mediatype_GetItemType, + mediatype_CompareItem, + mediatype_Compare, + mediatype_GetUINT32, + mediatype_GetUINT64, + mediatype_GetDouble, + mediatype_GetGUID, + mediatype_GetStringLength, + mediatype_GetString, + mediatype_GetAllocatedString, + mediatype_GetBlobSize, + mediatype_GetBlob, + mediatype_GetAllocatedBlob, + mediatype_GetUnknown, + mediatype_SetItem, + mediatype_DeleteItem, + mediatype_DeleteAllItems, + mediatype_SetUINT32, + mediatype_SetUINT64, + mediatype_SetDouble, + mediatype_SetGUID, + mediatype_SetString, + mediatype_SetBlob, + mediatype_SetUnknown, + mediatype_LockStore, + mediatype_UnlockStore, + mediatype_GetCount, + mediatype_GetItemByIndex, + mediatype_CopyAllItems, + mediatype_GetMajorType, + mediatype_IsCompressedFormat, + mediatype_IsEqual, + mediatype_GetRepresentation, + mediatype_FreeRepresentation +}; + +/*********************************************************************** + * MFCreateMediaType (mfplat.@) + */ +HRESULT WINAPI MFCreateMediaType(IMFMediaType **media_type) +{ + struct media_type *object; + + TRACE("%p.\n", media_type); + + if (!media_type) + return E_INVALIDARG; + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + init_attribute_object(&object->attributes, 0); + object->IMFMediaType_iface.lpVtbl = &mediatypevtbl; + + *media_type = &object->IMFMediaType_iface; + + return S_OK; +} diff --git a/dlls/mfplat/mfplat_private.h b/dlls/mfplat/mfplat_private.h index ac35ff2dca..02bc2d9287 100644 --- a/dlls/mfplat/mfplat_private.h +++ b/dlls/mfplat/mfplat_private.h @@ -16,6 +16,16 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA */
+#include "mfapi.h" + +typedef struct attributes +{ + IMFAttributes IMFAttributes_iface; + LONG ref; +} mfattributes; + +extern void init_attribute_object(mfattributes *object, UINT32 size) DECLSPEC_HIDDEN; + extern void init_system_queues(void) DECLSPEC_HIDDEN; extern void shutdown_system_queues(void) DECLSPEC_HIDDEN; extern BOOL is_platform_locked(void) DECLSPEC_HIDDEN; diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index e3b0687711..0382b02a27 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -20,7 +20,6 @@
#define COBJMACROS
-#include "mfapi.h" #include "mferror.h"
#include "wine/debug.h"
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 323 ----------------------------------- dlls/mfplat/mediatype.c | 316 ++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat_private.h | 1 + 3 files changed, 317 insertions(+), 323 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 7d90c69418..743d5bdacd 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -28,7 +28,6 @@ #include "winreg.h"
#include "initguid.h" -#include "mfidl.h" #include "mferror.h"
#include "wine/heap.h" @@ -2800,328 +2799,6 @@ HRESULT WINAPI MFCreateEventQueue(IMFMediaEventQueue **queue) return S_OK; }
-typedef struct _mfdescriptor -{ - mfattributes attributes; - IMFStreamDescriptor IMFStreamDescriptor_iface; -} mfdescriptor; - -static inline mfdescriptor *impl_from_IMFStreamDescriptor(IMFStreamDescriptor *iface) -{ - return CONTAINING_RECORD(iface, mfdescriptor, IMFStreamDescriptor_iface); -} - -static HRESULT WINAPI mfdescriptor_QueryInterface(IMFStreamDescriptor *iface, REFIID riid, void **out) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - - TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out); - - if(IsEqualGUID(riid, &IID_IUnknown) || - IsEqualGUID(riid, &IID_IMFAttributes) || - IsEqualGUID(riid, &IID_IMFStreamDescriptor)) - { - *out = &This->IMFStreamDescriptor_iface; - } - else - { - FIXME("(%s, %p)\n", debugstr_guid(riid), out); - *out = NULL; - return E_NOINTERFACE; - } - - IUnknown_AddRef((IUnknown*)*out); - return S_OK; -} - -static ULONG WINAPI mfdescriptor_AddRef(IMFStreamDescriptor *iface) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - ULONG ref = InterlockedIncrement(&This->attributes.ref); - - TRACE("(%p) ref=%u\n", This, ref); - - return ref; -} - -static ULONG WINAPI mfdescriptor_Release(IMFStreamDescriptor *iface) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - ULONG ref = InterlockedDecrement(&This->attributes.ref); - - TRACE("(%p) ref=%u\n", This, ref); - - if (!ref) - { - heap_free(This); - } - - return ref; -} - -static HRESULT WINAPI mfdescriptor_GetItem(IMFStreamDescriptor *iface, REFGUID key, PROPVARIANT *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetItem(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_GetItemType(IMFStreamDescriptor *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetItemType(&This->attributes.IMFAttributes_iface, key, type); -} - -static HRESULT WINAPI mfdescriptor_CompareItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value, BOOL *result) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_CompareItem(&This->attributes.IMFAttributes_iface, key, value, result); -} - -static HRESULT WINAPI mfdescriptor_Compare(IMFStreamDescriptor *iface, IMFAttributes *theirs, MF_ATTRIBUTES_MATCH_TYPE type, - BOOL *result) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_Compare(&This->attributes.IMFAttributes_iface, theirs, type, result); -} - -static HRESULT WINAPI mfdescriptor_GetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetUINT32(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_GetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetUINT64(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_GetDouble(IMFStreamDescriptor *iface, REFGUID key, double *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetDouble(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_GetGUID(IMFStreamDescriptor *iface, REFGUID key, GUID *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetGUID(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_GetStringLength(IMFStreamDescriptor *iface, REFGUID key, UINT32 *length) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetStringLength(&This->attributes.IMFAttributes_iface, key, length); -} - -static HRESULT WINAPI mfdescriptor_GetString(IMFStreamDescriptor *iface, REFGUID key, WCHAR *value, - UINT32 size, UINT32 *length) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetString(&This->attributes.IMFAttributes_iface, key, value, size, length); -} - -static HRESULT WINAPI mfdescriptor_GetAllocatedString(IMFStreamDescriptor *iface, REFGUID key, - WCHAR **value, UINT32 *length) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetAllocatedString(&This->attributes.IMFAttributes_iface, key, value, length); -} - -static HRESULT WINAPI mfdescriptor_GetBlobSize(IMFStreamDescriptor *iface, REFGUID key, UINT32 *size) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetBlobSize(&This->attributes.IMFAttributes_iface, key, size); -} - -static HRESULT WINAPI mfdescriptor_GetBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 *buf, - UINT32 bufsize, UINT32 *blobsize) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetBlob(&This->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); -} - -static HRESULT WINAPI mfdescriptor_GetAllocatedBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 **buf, UINT32 *size) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetAllocatedBlob(&This->attributes.IMFAttributes_iface, key, buf, size); -} - -static HRESULT WINAPI mfdescriptor_GetUnknown(IMFStreamDescriptor *iface, REFGUID key, REFIID riid, void **ppv) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetUnknown(&This->attributes.IMFAttributes_iface, key, riid, ppv); -} - -static HRESULT WINAPI mfdescriptor_SetItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetItem(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_DeleteItem(IMFStreamDescriptor *iface, REFGUID key) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_DeleteItem(&This->attributes.IMFAttributes_iface, key); -} - -static HRESULT WINAPI mfdescriptor_DeleteAllItems(IMFStreamDescriptor *iface) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_DeleteAllItems(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mfdescriptor_SetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetUINT32(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_SetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetUINT64(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_SetDouble(IMFStreamDescriptor *iface, REFGUID key, double value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetDouble(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_SetGUID(IMFStreamDescriptor *iface, REFGUID key, REFGUID value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetGUID(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_SetString(IMFStreamDescriptor *iface, REFGUID key, const WCHAR *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetString(&This->attributes.IMFAttributes_iface, key, value); -} - -static HRESULT WINAPI mfdescriptor_SetBlob(IMFStreamDescriptor *iface, REFGUID key, const UINT8 *buf, UINT32 size) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetBlob(&This->attributes.IMFAttributes_iface, key, buf, size); -} - -static HRESULT WINAPI mfdescriptor_SetUnknown(IMFStreamDescriptor *iface, REFGUID key, IUnknown *unknown) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_SetUnknown(&This->attributes.IMFAttributes_iface, key, unknown); -} - -static HRESULT WINAPI mfdescriptor_LockStore(IMFStreamDescriptor *iface) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_LockStore(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mfdescriptor_UnlockStore(IMFStreamDescriptor *iface) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_UnlockStore(&This->attributes.IMFAttributes_iface); -} - -static HRESULT WINAPI mfdescriptor_GetCount(IMFStreamDescriptor *iface, UINT32 *items) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetCount(&This->attributes.IMFAttributes_iface, items); -} - -static HRESULT WINAPI mfdescriptor_GetItemByIndex(IMFStreamDescriptor *iface, UINT32 index, GUID *key, PROPVARIANT *value) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - return IMFAttributes_GetItemByIndex(&This->attributes.IMFAttributes_iface, index, key, value); -} - -static HRESULT WINAPI mfdescriptor_CopyAllItems(IMFStreamDescriptor *iface, IMFAttributes *dest) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - - FIXME("%p, %p\n", This, dest); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfdescriptor_GetStreamIdentifier(IMFStreamDescriptor *iface, DWORD *identifier) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - - FIXME("%p, %p\n", This, identifier); - - return E_NOTIMPL; -} - -static HRESULT WINAPI mfdescriptor_GetMediaTypeHandler(IMFStreamDescriptor *iface, IMFMediaTypeHandler **handler) -{ - mfdescriptor *This = impl_from_IMFStreamDescriptor(iface); - - FIXME("%p, %p\n", This, handler); - - return E_NOTIMPL; -} - -static const IMFStreamDescriptorVtbl mfdescriptor_vtbl = -{ - mfdescriptor_QueryInterface, - mfdescriptor_AddRef, - mfdescriptor_Release, - mfdescriptor_GetItem, - mfdescriptor_GetItemType, - mfdescriptor_CompareItem, - mfdescriptor_Compare, - mfdescriptor_GetUINT32, - mfdescriptor_GetUINT64, - mfdescriptor_GetDouble, - mfdescriptor_GetGUID, - mfdescriptor_GetStringLength, - mfdescriptor_GetString, - mfdescriptor_GetAllocatedString, - mfdescriptor_GetBlobSize, - mfdescriptor_GetBlob, - mfdescriptor_GetAllocatedBlob, - mfdescriptor_GetUnknown, - mfdescriptor_SetItem, - mfdescriptor_DeleteItem, - mfdescriptor_DeleteAllItems, - mfdescriptor_SetUINT32, - mfdescriptor_SetUINT64, - mfdescriptor_SetDouble, - mfdescriptor_SetGUID, - mfdescriptor_SetString, - mfdescriptor_SetBlob, - mfdescriptor_SetUnknown, - mfdescriptor_LockStore, - mfdescriptor_UnlockStore, - mfdescriptor_GetCount, - mfdescriptor_GetItemByIndex, - mfdescriptor_CopyAllItems, - mfdescriptor_GetStreamIdentifier, - mfdescriptor_GetMediaTypeHandler -}; - -HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count, - IMFMediaType **types, IMFStreamDescriptor **descriptor) -{ - mfdescriptor *object; - - TRACE("%d, %d, %p, %p\n", identifier, count, types, descriptor); - - object = heap_alloc(sizeof(*object)); - if(!object) - return E_OUTOFMEMORY; - - init_attribute_object(&object->attributes, 0); - object->IMFStreamDescriptor_iface.lpVtbl = &mfdescriptor_vtbl; - *descriptor = &object->IMFStreamDescriptor_iface; - - return S_OK; -} - - typedef struct _mfbuffer { IMFMediaBuffer IMFMediaBuffer_iface; diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index b3292a61fe..11f5eab8d4 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -31,11 +31,22 @@ struct media_type IMFMediaType IMFMediaType_iface; };
+struct stream_desc +{ + struct attributes attributes; + IMFStreamDescriptor IMFStreamDescriptor_iface; +}; + static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface) { return CONTAINING_RECORD(iface, struct media_type, IMFMediaType_iface); }
+static inline struct stream_desc *impl_from_IMFStreamDescriptor(IMFStreamDescriptor *iface) +{ + return CONTAINING_RECORD(iface, struct stream_desc, IMFStreamDescriptor_iface); +} + static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); @@ -364,3 +375,308 @@ HRESULT WINAPI MFCreateMediaType(IMFMediaType **media_type)
return S_OK; } + + +static HRESULT WINAPI stream_descriptor_QueryInterface(IMFStreamDescriptor *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFStreamDescriptor) || + IsEqualIID(riid, &IID_IMFAttributes) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFStreamDescriptor_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI stream_descriptor_AddRef(IMFStreamDescriptor *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + ULONG refcount = InterlockedIncrement(&stream_desc->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI stream_descriptor_Release(IMFStreamDescriptor *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + ULONG refcount = InterlockedDecrement(&stream_desc->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + heap_free(stream_desc); + } + + return refcount; +} + +static HRESULT WINAPI stream_descriptor_GetItem(IMFStreamDescriptor *iface, REFGUID key, PROPVARIANT *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetItem(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_GetItemType(IMFStreamDescriptor *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetItemType(&stream_desc->attributes.IMFAttributes_iface, key, type); +} + +static HRESULT WINAPI stream_descriptor_CompareItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value, + BOOL *result) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_CompareItem(&stream_desc->attributes.IMFAttributes_iface, key, value, result); +} + +static HRESULT WINAPI stream_descriptor_Compare(IMFStreamDescriptor *iface, IMFAttributes *theirs, + MF_ATTRIBUTES_MATCH_TYPE type, BOOL *result) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_Compare(&stream_desc->attributes.IMFAttributes_iface, theirs, type, result); +} + +static HRESULT WINAPI stream_descriptor_GetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetUINT32(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_GetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetUINT64(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_GetDouble(IMFStreamDescriptor *iface, REFGUID key, double *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetDouble(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_GetGUID(IMFStreamDescriptor *iface, REFGUID key, GUID *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetGUID(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_GetStringLength(IMFStreamDescriptor *iface, REFGUID key, UINT32 *length) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetStringLength(&stream_desc->attributes.IMFAttributes_iface, key, length); +} + +static HRESULT WINAPI stream_descriptor_GetString(IMFStreamDescriptor *iface, REFGUID key, WCHAR *value, + UINT32 size, UINT32 *length) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetString(&stream_desc->attributes.IMFAttributes_iface, key, value, size, length); +} + +static HRESULT WINAPI stream_descriptor_GetAllocatedString(IMFStreamDescriptor *iface, REFGUID key, + WCHAR **value, UINT32 *length) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetAllocatedString(&stream_desc->attributes.IMFAttributes_iface, key, value, length); +} + +static HRESULT WINAPI stream_descriptor_GetBlobSize(IMFStreamDescriptor *iface, REFGUID key, UINT32 *size) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetBlobSize(&stream_desc->attributes.IMFAttributes_iface, key, size); +} + +static HRESULT WINAPI stream_descriptor_GetBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 *buf, + UINT32 bufsize, UINT32 *blobsize) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetBlob(&stream_desc->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); +} + +static HRESULT WINAPI stream_descriptor_GetAllocatedBlob(IMFStreamDescriptor *iface, REFGUID key, UINT8 **buf, + UINT32 *size) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetAllocatedBlob(&stream_desc->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI stream_descriptor_GetUnknown(IMFStreamDescriptor *iface, REFGUID key, REFIID riid, void **ppv) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetUnknown(&stream_desc->attributes.IMFAttributes_iface, key, riid, ppv); +} + +static HRESULT WINAPI stream_descriptor_SetItem(IMFStreamDescriptor *iface, REFGUID key, REFPROPVARIANT value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetItem(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_DeleteItem(IMFStreamDescriptor *iface, REFGUID key) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_DeleteItem(&stream_desc->attributes.IMFAttributes_iface, key); +} + +static HRESULT WINAPI stream_descriptor_DeleteAllItems(IMFStreamDescriptor *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_DeleteAllItems(&stream_desc->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI stream_descriptor_SetUINT32(IMFStreamDescriptor *iface, REFGUID key, UINT32 value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetUINT32(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_SetUINT64(IMFStreamDescriptor *iface, REFGUID key, UINT64 value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetUINT64(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_SetDouble(IMFStreamDescriptor *iface, REFGUID key, double value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetDouble(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_SetGUID(IMFStreamDescriptor *iface, REFGUID key, REFGUID value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetGUID(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_SetString(IMFStreamDescriptor *iface, REFGUID key, const WCHAR *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetString(&stream_desc->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI stream_descriptor_SetBlob(IMFStreamDescriptor *iface, REFGUID key, const UINT8 *buf, UINT32 size) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetBlob(&stream_desc->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI stream_descriptor_SetUnknown(IMFStreamDescriptor *iface, REFGUID key, IUnknown *unknown) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_SetUnknown(&stream_desc->attributes.IMFAttributes_iface, key, unknown); +} + +static HRESULT WINAPI stream_descriptor_LockStore(IMFStreamDescriptor *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_LockStore(&stream_desc->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI stream_descriptor_UnlockStore(IMFStreamDescriptor *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_UnlockStore(&stream_desc->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI stream_descriptor_GetCount(IMFStreamDescriptor *iface, UINT32 *items) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetCount(&stream_desc->attributes.IMFAttributes_iface, items); +} + +static HRESULT WINAPI stream_descriptor_GetItemByIndex(IMFStreamDescriptor *iface, UINT32 index, GUID *key, PROPVARIANT *value) +{ + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); + return IMFAttributes_GetItemByIndex(&stream_desc->attributes.IMFAttributes_iface, index, key, value); +} + +static HRESULT WINAPI stream_descriptor_CopyAllItems(IMFStreamDescriptor *iface, IMFAttributes *dest) +{ + FIXME("%p, %p.\n", iface, dest); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_descriptor_GetStreamIdentifier(IMFStreamDescriptor *iface, DWORD *identifier) +{ + FIXME("%p, %p.\n", iface, identifier); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_descriptor_GetMediaTypeHandler(IMFStreamDescriptor *iface, IMFMediaTypeHandler **handler) +{ + FIXME("%p, %p.\n", iface, handler); + + return E_NOTIMPL; +} + +static const IMFStreamDescriptorVtbl streamdescriptorvtbl = +{ + stream_descriptor_QueryInterface, + stream_descriptor_AddRef, + stream_descriptor_Release, + stream_descriptor_GetItem, + stream_descriptor_GetItemType, + stream_descriptor_CompareItem, + stream_descriptor_Compare, + stream_descriptor_GetUINT32, + stream_descriptor_GetUINT64, + stream_descriptor_GetDouble, + stream_descriptor_GetGUID, + stream_descriptor_GetStringLength, + stream_descriptor_GetString, + stream_descriptor_GetAllocatedString, + stream_descriptor_GetBlobSize, + stream_descriptor_GetBlob, + stream_descriptor_GetAllocatedBlob, + stream_descriptor_GetUnknown, + stream_descriptor_SetItem, + stream_descriptor_DeleteItem, + stream_descriptor_DeleteAllItems, + stream_descriptor_SetUINT32, + stream_descriptor_SetUINT64, + stream_descriptor_SetDouble, + stream_descriptor_SetGUID, + stream_descriptor_SetString, + stream_descriptor_SetBlob, + stream_descriptor_SetUnknown, + stream_descriptor_LockStore, + stream_descriptor_UnlockStore, + stream_descriptor_GetCount, + stream_descriptor_GetItemByIndex, + stream_descriptor_CopyAllItems, + stream_descriptor_GetStreamIdentifier, + stream_descriptor_GetMediaTypeHandler +}; + +/*********************************************************************** + * MFCreateStreamDescriptor (mfplat.@) + */ +HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count, + IMFMediaType **types, IMFStreamDescriptor **descriptor) +{ + struct stream_desc *object; + + TRACE("%d, %d, %p, %p.\n", identifier, count, types, descriptor); + + object = heap_alloc(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + init_attribute_object(&object->attributes, 0); + object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl; + *descriptor = &object->IMFStreamDescriptor_iface; + + return S_OK; +} diff --git a/dlls/mfplat/mfplat_private.h b/dlls/mfplat/mfplat_private.h index 02bc2d9287..46320bbb50 100644 --- a/dlls/mfplat/mfplat_private.h +++ b/dlls/mfplat/mfplat_private.h @@ -17,6 +17,7 @@ */
#include "mfapi.h" +#include "mfidl.h"
typedef struct attributes {
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 102 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 11f5eab8d4..79d34405fe 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -35,6 +35,7 @@ struct stream_desc { struct attributes attributes; IMFStreamDescriptor IMFStreamDescriptor_iface; + IMFMediaTypeHandler IMFMediaTypeHandler_iface; };
static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface) @@ -47,6 +48,11 @@ static inline struct stream_desc *impl_from_IMFStreamDescriptor(IMFStreamDescrip return CONTAINING_RECORD(iface, struct stream_desc, IMFStreamDescriptor_iface); }
+static struct stream_desc *impl_from_IMFMediaTypeHandler(IMFMediaTypeHandler *iface) +{ + return CONTAINING_RECORD(iface, struct stream_desc, IMFMediaTypeHandler_iface); +} + static HRESULT WINAPI mediatype_QueryInterface(IMFMediaType *iface, REFIID riid, void **out) { TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); @@ -616,9 +622,14 @@ static HRESULT WINAPI stream_descriptor_GetStreamIdentifier(IMFStreamDescriptor
static HRESULT WINAPI stream_descriptor_GetMediaTypeHandler(IMFStreamDescriptor *iface, IMFMediaTypeHandler **handler) { - FIXME("%p, %p.\n", iface, handler); + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, handler); + + *handler = &stream_desc->IMFMediaTypeHandler_iface; + IMFStreamDescriptor_AddRef(iface); + + return S_OK; }
static const IMFStreamDescriptorVtbl streamdescriptorvtbl = @@ -660,6 +671,92 @@ static const IMFStreamDescriptorVtbl streamdescriptorvtbl = stream_descriptor_GetMediaTypeHandler };
+static HRESULT WINAPI mediatype_handler_QueryInterface(IMFMediaTypeHandler *iface, REFIID riid, void **obj) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + if (IsEqualIID(riid, &IID_IMFMediaTypeHandler) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IMFMediaTypeHandler_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI mediatype_handler_AddRef(IMFMediaTypeHandler *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamDescriptor_AddRef(&stream_desc->IMFStreamDescriptor_iface); +} + +static ULONG WINAPI mediatype_handler_Release(IMFMediaTypeHandler *iface) +{ + struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface); + return IMFStreamDescriptor_Release(&stream_desc->IMFStreamDescriptor_iface); +} + +static HRESULT WINAPI mediatype_handler_IsMediaTypeSupported(IMFMediaTypeHandler *iface, IMFMediaType *in_type, + IMFMediaType **out_type) +{ + FIXME("%p, %p, %p.\n", iface, in_type, out_type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count) +{ + FIXME("%p, %p.\n", iface, count); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index, + IMFMediaType **type) +{ + FIXME("%p, %u, %p.\n", iface, index, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType *type) +{ + FIXME("%p, %p.\n", iface, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType **type) +{ + FIXME("%p, %p.\n", iface, type); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mediatype_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type) +{ + FIXME("%p, %p.\n", iface, type); + + return E_NOTIMPL; +} + +static const IMFMediaTypeHandlerVtbl mediatypehandlervtbl = +{ + mediatype_handler_QueryInterface, + mediatype_handler_AddRef, + mediatype_handler_Release, + mediatype_handler_IsMediaTypeSupported, + mediatype_handler_GetMediaTypeCount, + mediatype_handler_GetMediaTypeByIndex, + mediatype_handler_SetCurrentMediaType, + mediatype_handler_GetCurrentMediaType, + mediatype_handler_GetMajorType, +}; + /*********************************************************************** * MFCreateStreamDescriptor (mfplat.@) */ @@ -676,6 +773,7 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count,
init_attribute_object(&object->attributes, 0); object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl; + object->IMFMediaTypeHandler_iface.lpVtbl = &mediatypehandlervtbl; *descriptor = &object->IMFStreamDescriptor_iface;
return S_OK;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/mediatype.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 79d34405fe..1bd32cd8b0 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -36,6 +36,7 @@ struct stream_desc struct attributes attributes; IMFStreamDescriptor IMFStreamDescriptor_iface; IMFMediaTypeHandler IMFMediaTypeHandler_iface; + DWORD identifier; };
static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface) @@ -615,9 +616,13 @@ static HRESULT WINAPI stream_descriptor_CopyAllItems(IMFStreamDescriptor *iface,
static HRESULT WINAPI stream_descriptor_GetStreamIdentifier(IMFStreamDescriptor *iface, DWORD *identifier) { - FIXME("%p, %p.\n", iface, identifier); + struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, identifier); + + *identifier = stream_desc->identifier; + + return S_OK; }
static HRESULT WINAPI stream_descriptor_GetMediaTypeHandler(IMFStreamDescriptor *iface, IMFMediaTypeHandler **handler) @@ -774,6 +779,8 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count, init_attribute_object(&object->attributes, 0); object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl; object->IMFMediaTypeHandler_iface.lpVtbl = &mediatypehandlervtbl; + object->identifier = identifier; + *descriptor = &object->IMFStreamDescriptor_iface;
return S_OK;
Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 1 - dlls/mfplat/mediatype.c | 90 ++++++++++++++++++++++++++++++++---- dlls/mfplat/mfplat_private.h | 1 + dlls/mfplat/queue.c | 2 - 4 files changed, 82 insertions(+), 12 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 743d5bdacd..2217f3fb94 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -28,7 +28,6 @@ #include "winreg.h"
#include "initguid.h" -#include "mferror.h"
#include "wine/heap.h" #include "wine/debug.h" diff --git a/dlls/mfplat/mediatype.c b/dlls/mfplat/mediatype.c index 1bd32cd8b0..a473c755d9 100644 --- a/dlls/mfplat/mediatype.c +++ b/dlls/mfplat/mediatype.c @@ -37,6 +37,10 @@ struct stream_desc IMFStreamDescriptor IMFStreamDescriptor_iface; IMFMediaTypeHandler IMFMediaTypeHandler_iface; DWORD identifier; + IMFMediaType **media_types; + unsigned int media_types_count; + IMFMediaType *current_type; + CRITICAL_SECTION cs; };
static inline struct media_type *impl_from_IMFMediaType(IMFMediaType *iface) @@ -416,11 +420,21 @@ static ULONG WINAPI stream_descriptor_Release(IMFStreamDescriptor *iface) { struct stream_desc *stream_desc = impl_from_IMFStreamDescriptor(iface); ULONG refcount = InterlockedDecrement(&stream_desc->attributes.ref); + unsigned int i;
TRACE("%p, refcount %u.\n", iface, refcount);
if (!refcount) { + for (i = 0; i < stream_desc->media_types_count; ++i) + { + if (stream_desc->media_types[i]) + IMFMediaType_Release(stream_desc->media_types[i]); + } + heap_free(stream_desc->media_types); + if (stream_desc->current_type) + IMFMediaType_Release(stream_desc->current_type); + DeleteCriticalSection(&stream_desc->cs); heap_free(stream_desc); }
@@ -715,31 +729,71 @@ static HRESULT WINAPI mediatype_handler_IsMediaTypeSupported(IMFMediaTypeHandler
static HRESULT WINAPI mediatype_handler_GetMediaTypeCount(IMFMediaTypeHandler *iface, DWORD *count) { - FIXME("%p, %p.\n", iface, count); + struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, count); + + *count = stream_desc->media_types_count; + + return S_OK; }
static HRESULT WINAPI mediatype_handler_GetMediaTypeByIndex(IMFMediaTypeHandler *iface, DWORD index, IMFMediaType **type) { - FIXME("%p, %u, %p.\n", iface, index, type); + struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
- return E_NOTIMPL; + TRACE("%p, %u, %p.\n", iface, index, type); + + if (index >= stream_desc->media_types_count) + return MF_E_NO_MORE_TYPES; + + if (stream_desc->media_types[index]) + { + *type = stream_desc->media_types[index]; + IMFMediaType_AddRef(*type); + } + + return stream_desc->media_types[index] ? S_OK : E_FAIL; }
static HRESULT WINAPI mediatype_handler_SetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType *type) { - FIXME("%p, %p.\n", iface, type); + struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface);
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, type); + + if (!type) + return E_POINTER; + + EnterCriticalSection(&stream_desc->cs); + if (stream_desc->current_type) + IMFMediaType_Release(stream_desc->current_type); + stream_desc->current_type = type; + IMFMediaType_AddRef(stream_desc->current_type); + LeaveCriticalSection(&stream_desc->cs); + + return S_OK; }
static HRESULT WINAPI mediatype_handler_GetCurrentMediaType(IMFMediaTypeHandler *iface, IMFMediaType **type) { - FIXME("%p, %p.\n", iface, type); + struct stream_desc *stream_desc = impl_from_IMFMediaTypeHandler(iface); + HRESULT hr = S_OK;
- return E_NOTIMPL; + TRACE("%p, %p.\n", iface, type); + + EnterCriticalSection(&stream_desc->cs); + if (stream_desc->current_type) + { + *type = stream_desc->current_type; + IMFMediaType_AddRef(*type); + } + else + hr = MF_E_NOT_INITIALIZED; + LeaveCriticalSection(&stream_desc->cs); + + return hr; }
static HRESULT WINAPI mediatype_handler_GetMajorType(IMFMediaTypeHandler *iface, GUID *type) @@ -769,10 +823,14 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count, IMFMediaType **types, IMFStreamDescriptor **descriptor) { struct stream_desc *object; + unsigned int i;
TRACE("%d, %d, %p, %p.\n", identifier, count, types, descriptor);
- object = heap_alloc(sizeof(*object)); + if (!count) + return E_INVALIDARG; + + object = heap_alloc_zero(sizeof(*object)); if (!object) return E_OUTOFMEMORY;
@@ -780,6 +838,20 @@ HRESULT WINAPI MFCreateStreamDescriptor(DWORD identifier, DWORD count, object->IMFStreamDescriptor_iface.lpVtbl = &streamdescriptorvtbl; object->IMFMediaTypeHandler_iface.lpVtbl = &mediatypehandlervtbl; object->identifier = identifier; + object->media_types = heap_alloc(count * sizeof(*object->media_types)); + if (!object->media_types) + { + heap_free(object); + return E_OUTOFMEMORY; + } + for (i = 0; i < count; ++i) + { + object->media_types[i] = types[i]; + if (object->media_types[i]) + IMFMediaType_AddRef(object->media_types[i]); + } + object->media_types_count = count; + InitializeCriticalSection(&object->cs);
*descriptor = &object->IMFStreamDescriptor_iface;
diff --git a/dlls/mfplat/mfplat_private.h b/dlls/mfplat/mfplat_private.h index 46320bbb50..e5b0647e63 100644 --- a/dlls/mfplat/mfplat_private.h +++ b/dlls/mfplat/mfplat_private.h @@ -18,6 +18,7 @@
#include "mfapi.h" #include "mfidl.h" +#include "mferror.h"
typedef struct attributes { diff --git a/dlls/mfplat/queue.c b/dlls/mfplat/queue.c index 0382b02a27..4d3322840c 100644 --- a/dlls/mfplat/queue.c +++ b/dlls/mfplat/queue.c @@ -20,8 +20,6 @@
#define COBJMACROS
-#include "mferror.h" - #include "wine/debug.h" #include "wine/heap.h" #include "wine/list.h"
March 4, 2019 4:34 AM, "Nikolay Sivov" nsivov@codeweavers.com wrote:
diff --git a/include/mfapi.h b/include/mfapi.h index ee5cf4c069..129a19c883 100644 --- a/include/mfapi.h +++ b/include/mfapi.h @@ -95,6 +95,9 @@ typedef enum MF_MULTITHREADED_WORKQUEUE, } MFASYNC_WORKQUEUE_TYPE;
+typedef void (*CALLBACK MFPERIODICCALLBACK)(IUnknown *context);
Shouldn't the asterisk come after the calling convention?
Chip