Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mfplat/main.c | 416 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/mfplat.spec | 2 +- dlls/mfplat/tests/mfplat.c | 25 +++ include/mftransform.idl | 2 + 4 files changed, 444 insertions(+), 1 deletion(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 910b923542..df11e189a2 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -65,6 +65,12 @@ static CRITICAL_SECTION local_handlers_section = { NULL, -1, 0, 0, 0, 0 }; static struct list local_scheme_handlers = LIST_INIT(local_scheme_handlers); static struct list local_bytestream_handlers = LIST_INIT(local_bytestream_handlers);
+struct transform_activate +{ + struct attributes attributes; + IMFActivate IMFActivate_iface; +}; + struct system_clock { IMFClock IMFClock_iface; @@ -107,6 +113,416 @@ static struct system_clock *impl_from_IMFClock(IMFClock *iface) return CONTAINING_RECORD(iface, struct system_clock, IMFClock_iface); }
+static struct transform_activate *impl_from_IMFActivate(IMFActivate *iface) +{ + return CONTAINING_RECORD(iface, struct transform_activate, IMFActivate_iface); +} + +static HRESULT WINAPI transform_activate_QueryInterface(IMFActivate *iface, REFIID riid, void **out) +{ + TRACE("%p, %s, %p.\n", iface, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFActivate) || + IsEqualIID(riid, &IID_IMFAttributes) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + IMFActivate_AddRef(iface); + return S_OK; + } + + WARN("Unsupported %s.\n", debugstr_guid(riid)); + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI transform_activate_AddRef(IMFActivate *iface) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + ULONG refcount = InterlockedIncrement(&activate->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + return refcount; +} + +static ULONG WINAPI transform_activate_Release(IMFActivate *iface) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + ULONG refcount = InterlockedDecrement(&activate->attributes.ref); + + TRACE("%p, refcount %u.\n", iface, refcount); + + if (!refcount) + { + clear_attributes_object(&activate->attributes); + heap_free(activate); + } + + return refcount; +} + +static HRESULT WINAPI transform_activate_GetItem(IMFActivate *iface, REFGUID key, PROPVARIANT *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value); + + return attributes_GetItem(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_GetItemType(IMFActivate *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), type); + + return attributes_GetItemType(&activate->attributes, key, type); +} + +static HRESULT WINAPI transform_activate_CompareItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value, + BOOL *result) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_propvar(value), result); + + return attributes_CompareItem(&activate->attributes, key, value, result); +} + +static HRESULT WINAPI transform_activate_Compare(IMFActivate *iface, IMFAttributes *theirs, + MF_ATTRIBUTES_MATCH_TYPE match_type, BOOL *ret) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %p, %d, %p.\n", iface, theirs, match_type, ret); + + return attributes_Compare(&activate->attributes, theirs, match_type, ret); +} + +static HRESULT WINAPI transform_activate_GetUINT32(IMFActivate *iface, REFGUID key, UINT32 *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value); + + return attributes_GetUINT32(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_GetUINT64(IMFActivate *iface, REFGUID key, UINT64 *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value); + + return attributes_GetUINT64(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_GetDouble(IMFActivate *iface, REFGUID key, double *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value); + + return attributes_GetDouble(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_GetGUID(IMFActivate *iface, REFGUID key, GUID *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), value); + + return attributes_GetGUID(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_GetStringLength(IMFActivate *iface, REFGUID key, UINT32 *length) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), length); + + return attributes_GetStringLength(&activate->attributes, key, length); +} + +static HRESULT WINAPI transform_activate_GetString(IMFActivate *iface, REFGUID key, WCHAR *value, + UINT32 size, UINT32 *length) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p, %d, %p.\n", iface, debugstr_attr(key), value, size, length); + + return attributes_GetString(&activate->attributes, key, value, size, length); +} + +static HRESULT WINAPI transform_activate_GetAllocatedString(IMFActivate *iface, REFGUID key, WCHAR **value, + UINT32 *length) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), value, length); + + return attributes_GetAllocatedString(&activate->attributes, key, value, length); +} + +static HRESULT WINAPI transform_activate_GetBlobSize(IMFActivate *iface, REFGUID key, UINT32 *size) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), size); + + return attributes_GetBlobSize(&activate->attributes, key, size); +} + +static HRESULT WINAPI transform_activate_GetBlob(IMFActivate *iface, REFGUID key, UINT8 *buf, UINT32 bufsize, + UINT32 *blobsize) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p, %d, %p.\n", iface, debugstr_attr(key), buf, bufsize, blobsize); + + return attributes_GetBlob(&activate->attributes, key, buf, bufsize, blobsize); +} + +static HRESULT WINAPI transform_activate_GetAllocatedBlob(IMFActivate *iface, REFGUID key, UINT8 **buf, UINT32 *size) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p, %p.\n", iface, debugstr_attr(key), buf, size); + + return attributes_GetAllocatedBlob(&activate->attributes, key, buf, size); +} + +static HRESULT WINAPI transform_activate_GetUnknown(IMFActivate *iface, REFGUID key, REFIID riid, void **out) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %s, %p.\n", iface, debugstr_attr(key), debugstr_guid(riid), out); + + return attributes_GetUnknown(&activate->attributes, key, riid, out); +} + +static HRESULT WINAPI transform_activate_SetItem(IMFActivate *iface, REFGUID key, REFPROPVARIANT value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_propvar(value)); + + return attributes_SetItem(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_DeleteItem(IMFActivate *iface, REFGUID key) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s.\n", iface, debugstr_attr(key)); + + return attributes_DeleteItem(&activate->attributes, key); +} + +static HRESULT WINAPI transform_activate_DeleteAllItems(IMFActivate *iface) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p.\n", iface); + + return attributes_DeleteAllItems(&activate->attributes); +} + +static HRESULT WINAPI transform_activate_SetUINT32(IMFActivate *iface, REFGUID key, UINT32 value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %u.\n", iface, debugstr_attr(key), value); + + return attributes_SetUINT32(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_SetUINT64(IMFActivate *iface, REFGUID key, UINT64 value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), wine_dbgstr_longlong(value)); + + return attributes_SetUINT64(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_SetDouble(IMFActivate *iface, REFGUID key, double value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %f.\n", iface, debugstr_attr(key), value); + + return attributes_SetDouble(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_SetGUID(IMFActivate *iface, REFGUID key, REFGUID value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_mf_guid(value)); + + return attributes_SetGUID(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_SetString(IMFActivate *iface, REFGUID key, const WCHAR *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %s.\n", iface, debugstr_attr(key), debugstr_w(value)); + + return attributes_SetString(&activate->attributes, key, value); +} + +static HRESULT WINAPI transform_activate_SetBlob(IMFActivate *iface, REFGUID key, const UINT8 *buf, UINT32 size) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p, %u.\n", iface, debugstr_attr(key), buf, size); + + return attributes_SetBlob(&activate->attributes, key, buf, size); +} + +static HRESULT WINAPI transform_activate_SetUnknown(IMFActivate *iface, REFGUID key, IUnknown *unknown) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %s, %p.\n", iface, debugstr_attr(key), unknown); + + return attributes_SetUnknown(&activate->attributes, key, unknown); +} + +static HRESULT WINAPI transform_activate_LockStore(IMFActivate *iface) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p.\n", iface); + + return attributes_LockStore(&activate->attributes); +} + +static HRESULT WINAPI transform_activate_UnlockStore(IMFActivate *iface) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p.\n", iface); + + return attributes_UnlockStore(&activate->attributes); +} + +static HRESULT WINAPI transform_activate_GetCount(IMFActivate *iface, UINT32 *count) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %p.\n", iface, count); + + return attributes_GetCount(&activate->attributes, count); +} + +static HRESULT WINAPI transform_activate_GetItemByIndex(IMFActivate *iface, UINT32 index, GUID *key, + PROPVARIANT *value) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %u, %p, %p.\n", iface, index, key, value); + + return attributes_GetItemByIndex(&activate->attributes, index, key, value); +} + +static HRESULT WINAPI transform_activate_CopyAllItems(IMFActivate *iface, IMFAttributes *dest) +{ + struct transform_activate *activate = impl_from_IMFActivate(iface); + + TRACE("%p, %p.\n", iface, dest); + + return attributes_CopyAllItems(&activate->attributes, dest); +} + +static HRESULT WINAPI transform_activate_ActivateObject(IMFActivate *iface, REFIID riid, void **obj) +{ + FIXME("%p, %s, %p.\n", iface, debugstr_guid(riid), obj); + + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_activate_ShutdownObject(IMFActivate *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static HRESULT WINAPI transform_activate_DetachObject(IMFActivate *iface) +{ + FIXME("%p.\n", iface); + + return E_NOTIMPL; +} + +static const IMFActivateVtbl transform_activate_vtbl = +{ + transform_activate_QueryInterface, + transform_activate_AddRef, + transform_activate_Release, + transform_activate_GetItem, + transform_activate_GetItemType, + transform_activate_CompareItem, + transform_activate_Compare, + transform_activate_GetUINT32, + transform_activate_GetUINT64, + transform_activate_GetDouble, + transform_activate_GetGUID, + transform_activate_GetStringLength, + transform_activate_GetString, + transform_activate_GetAllocatedString, + transform_activate_GetBlobSize, + transform_activate_GetBlob, + transform_activate_GetAllocatedBlob, + transform_activate_GetUnknown, + transform_activate_SetItem, + transform_activate_DeleteItem, + transform_activate_DeleteAllItems, + transform_activate_SetUINT32, + transform_activate_SetUINT64, + transform_activate_SetDouble, + transform_activate_SetGUID, + transform_activate_SetString, + transform_activate_SetBlob, + transform_activate_SetUnknown, + transform_activate_LockStore, + transform_activate_UnlockStore, + transform_activate_GetCount, + transform_activate_GetItemByIndex, + transform_activate_CopyAllItems, + transform_activate_ActivateObject, + transform_activate_ShutdownObject, + transform_activate_DetachObject, +}; + +HRESULT WINAPI MFCreateTransformActivate(IMFActivate **activate) +{ + struct transform_activate *object; + HRESULT hr; + + TRACE("%p.\n", activate); + + object = heap_alloc_zero(sizeof(*object)); + if (!object) + return E_OUTOFMEMORY; + + if (FAILED(hr = init_attributes_object(&object->attributes, 0))) + { + heap_free(object); + return hr; + } + + object->IMFActivate_iface.lpVtbl = &transform_activate_vtbl; + + *activate = &object->IMFActivate_iface; + + return S_OK; +} + static const WCHAR transform_keyW[] = {'M','e','d','i','a','F','o','u','n','d','a','t','i','o','n','\', 'T','r','a','n','s','f','o','r','m','s',0}; static const WCHAR categories_keyW[] = {'M','e','d','i','a','F','o','u','n','d','a','t','i','o','n','\', diff --git a/dlls/mfplat/mfplat.spec b/dlls/mfplat/mfplat.spec index e48242fa15..e3ec8bcb8b 100644 --- a/dlls/mfplat/mfplat.spec +++ b/dlls/mfplat/mfplat.spec @@ -66,7 +66,7 @@ @ stdcall MFCreateSystemTimeSource(ptr) @ stub MFCreateSystemUnderlyingClock @ stub MFCreateTempFile -@ stub MFCreateTransformActivate +@ stdcall MFCreateTransformActivate(ptr) @ stub MFCreateURLFromPath @ stub MFCreateUdpSockets @ stub MFCreateVideoMediaType diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index b61d91d14e..ba896f3711 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -77,6 +77,7 @@ static HRESULT (WINAPI *pMFRemovePeriodicCallback)(DWORD key); static HRESULT (WINAPI *pMFRegisterLocalByteStreamHandler)(const WCHAR *extension, const WCHAR *mime, IMFActivate *activate); static HRESULT (WINAPI *pMFRegisterLocalSchemeHandler)(const WCHAR *scheme, IMFActivate *activate); +static HRESULT (WINAPI *pMFCreateTransformActivate)(IMFActivate **activate);
static const WCHAR mp4file[] = {'t','e','s','t','.','m','p','4',0}; static const WCHAR fileschemeW[] = {'f','i','l','e',':','/','/',0}; @@ -527,6 +528,7 @@ static void init_functions(void) X(MFRegisterLocalByteStreamHandler); X(MFRegisterLocalSchemeHandler); X(MFRemovePeriodicCallback); + X(MFCreateTransformActivate); #undef X
if ((mod = LoadLibraryA("d3d11.dll"))) @@ -3799,6 +3801,28 @@ static void test_dxgi_device_manager(void) IMFDXGIDeviceManager_Release(manager2); }
+static void test_MFCreateTransformActivate(void) +{ + IMFActivate *activate; + UINT32 count; + HRESULT hr; + + if (!pMFCreateTransformActivate) + { + win_skip("MFCreateTransformActivate() is not available.\n"); + return; + } + + hr = pMFCreateTransformActivate(&activate); + ok(hr == S_OK, "Failed to create activator, hr %#x.\n", hr); + + hr = IMFActivate_GetCount(activate, &count); + ok(hr == S_OK, "Failed to get count, hr %#x.\n", hr); + ok(!count, "Unexpected attribute count %u.\n", count); + + IMFActivate_Release(activate); +} + START_TEST(mfplat) { CoInitialize(NULL); @@ -3837,6 +3861,7 @@ START_TEST(mfplat) test_local_handlers(); test_create_property_store(); test_dxgi_device_manager(); + test_MFCreateTransformActivate();
CoUninitialize(); } diff --git a/include/mftransform.idl b/include/mftransform.idl index ca2f781a6b..5c4860c367 100644 --- a/include/mftransform.idl +++ b/include/mftransform.idl @@ -121,3 +121,5 @@ interface IMFTransform : IUnknown [local] HRESULT ProcessOutput([in] DWORD flags, [in] DWORD count, [in,out,size_is(count)] MFT_OUTPUT_DATA_BUFFER *samples, [out] DWORD *status); } + +cpp_quote("HRESULT WINAPI MFCreateTransformActivate(IMFActivate **activate);")