Signed-off-by: Sven Baars sven.wine@gmail.com --- This patch follows suggestions from Nikolay and Zebediah to first implement a separate IMFAttributes interface for IMFByteStream.
v2: Split moving the IMFAttributes interface and actually adding the IMFAttributes interface to IMFByteStream. v3: Remove ref from mfbytestream. I missed this with rebasing.
dlls/mfplat/main.c | 323 ++++++++++++++++++++++++++++++++++++- dlls/mfplat/tests/mfplat.c | 53 +++++- 2 files changed, 368 insertions(+), 8 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index 598072121d..7865a8935f 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -847,8 +847,9 @@ HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size)
typedef struct _mfbytestream { + mfattributes attributes; IMFByteStream IMFByteStream_iface; - LONG ref; + IMFAttributes IMFAttributes_iface; } mfbytestream;
static inline mfbytestream *impl_from_IMFByteStream(IMFByteStream *iface) @@ -867,6 +868,10 @@ static HRESULT WINAPI mfbytestream_QueryInterface(IMFByteStream *iface, REFIID r { *out = &This->IMFByteStream_iface; } + else if(IsEqualGUID(riid, &IID_IMFAttributes)) + { + *out = &This->IMFAttributes_iface; + } else { FIXME("(%s, %p)\n", debugstr_guid(riid), out); @@ -881,7 +886,7 @@ static HRESULT WINAPI mfbytestream_QueryInterface(IMFByteStream *iface, REFIID r static ULONG WINAPI mfbytestream_AddRef(IMFByteStream *iface) { mfbytestream *This = impl_from_IMFByteStream(iface); - ULONG ref = InterlockedIncrement(&This->ref); + ULONG ref = InterlockedIncrement(&This->attributes.ref);
TRACE("(%p) ref=%u\n", This, ref);
@@ -891,7 +896,7 @@ static ULONG WINAPI mfbytestream_AddRef(IMFByteStream *iface) static ULONG WINAPI mfbytestream_Release(IMFByteStream *iface) { mfbytestream *This = impl_from_IMFByteStream(iface); - ULONG ref = InterlockedDecrement(&This->ref); + ULONG ref = InterlockedDecrement(&This->attributes.ref);
TRACE("(%p) ref=%u\n", This, ref);
@@ -1044,7 +1049,7 @@ static HRESULT WINAPI mfbytestream_Close(IMFByteStream *iface) return E_NOTIMPL; }
-static const IMFByteStreamVtbl mfbytesteam_vtbl = +static const IMFByteStreamVtbl mfbytestream_vtbl = { mfbytestream_QueryInterface, mfbytestream_AddRef, @@ -1066,6 +1071,311 @@ static const IMFByteStreamVtbl mfbytesteam_vtbl = mfbytestream_Close };
+static inline mfbytestream *impl_from_IMFByteStream_IMFAttributes(IMFAttributes *iface) +{ + return CONTAINING_RECORD(iface, mfbytestream, IMFAttributes_iface); +} + +static HRESULT WINAPI mfbytestream_mfattributes_QueryInterface( + IMFAttributes *iface, REFIID riid, void **out) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out); + + if(IsEqualGUID(riid, &IID_IUnknown) || + IsEqualGUID(riid, &IID_IMFByteStream)) + { + *out = &This->IMFByteStream_iface; + } + else if(IsEqualGUID(riid, &IID_IMFAttributes)) + { + *out = &This->IMFAttributes_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 mfbytestream_mfattributes_AddRef(IMFAttributes *iface) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + ULONG ref = InterlockedIncrement(&This->attributes.ref); + + TRACE("(%p) ref=%u\n", This, ref); + + return ref; +} + +static ULONG WINAPI mfbytestream_mfattributes_Release(IMFAttributes *iface) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(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 mfbytestream_mfattributes_GetItem( + IMFAttributes *iface, REFGUID key, PROPVARIANT *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetItem(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetItemType( + IMFAttributes *iface, REFGUID key, MF_ATTRIBUTE_TYPE *type) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetItemType(&This->attributes.IMFAttributes_iface, key, type); +} + +static HRESULT WINAPI mfbytestream_mfattributes_CompareItem( + IMFAttributes *iface, REFGUID key, REFPROPVARIANT value, BOOL *result) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_CompareItem(&This->attributes.IMFAttributes_iface, key, value, result); +} + +static HRESULT WINAPI mfbytestream_mfattributes_Compare( + IMFAttributes *iface, IMFAttributes *attrs, MF_ATTRIBUTES_MATCH_TYPE type, + BOOL *result) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_Compare(&This->attributes.IMFAttributes_iface, attrs, type, result); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetUINT32( + IMFAttributes *iface, REFGUID key, UINT32 *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetUINT32(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetUINT64( + IMFAttributes *iface, REFGUID key, UINT64 *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetUINT64(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetDouble( + IMFAttributes *iface, REFGUID key, double *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetDouble(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetGUID( + IMFAttributes *iface, REFGUID key, GUID *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetGUID(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetStringLength( + IMFAttributes *iface, REFGUID key, UINT32 *length) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetStringLength(&This->attributes.IMFAttributes_iface, key, length); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetString( + IMFAttributes *iface, REFGUID key, WCHAR *value, UINT32 size, UINT32 *length) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetString(&This->attributes.IMFAttributes_iface, key, value, size, length); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetAllocatedString( + IMFAttributes *iface, REFGUID key, WCHAR **value, UINT32 *length) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetAllocatedString(&This->attributes.IMFAttributes_iface, key, value, length); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetBlobSize( + IMFAttributes *iface, REFGUID key, UINT32 *size) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetBlobSize(&This->attributes.IMFAttributes_iface, key, size); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetBlob( + IMFAttributes *iface, REFGUID key, UINT8 *buf, UINT32 bufsize, UINT32 *blobsize) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetBlob(&This->attributes.IMFAttributes_iface, key, buf, bufsize, blobsize); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetAllocatedBlob( + IMFAttributes *iface, REFGUID key, UINT8 **buf, UINT32 *size) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetAllocatedBlob(&This->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetUnknown( + IMFAttributes *iface, REFGUID key, REFIID riid, void **ppv) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetUnknown(&This->attributes.IMFAttributes_iface, key, riid, ppv); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetItem( + IMFAttributes *iface, REFGUID key, REFPROPVARIANT value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetItem(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_DeleteItem( + IMFAttributes *iface, REFGUID key) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_DeleteItem(&This->attributes.IMFAttributes_iface, key); +} + +static HRESULT WINAPI mfbytestream_mfattributes_DeleteAllItems( + IMFAttributes *iface) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_DeleteAllItems(&This->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetUINT32( + IMFAttributes *iface, REFGUID key, UINT32 value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetUINT32(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetUINT64( + IMFAttributes *iface, REFGUID key, UINT64 value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetUINT64(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetDouble( + IMFAttributes *iface, REFGUID key, double value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetDouble(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetGUID( + IMFAttributes *iface, REFGUID key, REFGUID value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetGUID(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetString( + IMFAttributes *iface, REFGUID key, const WCHAR *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetString(&This->attributes.IMFAttributes_iface, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetBlob( + IMFAttributes *iface, REFGUID key, const UINT8 *buf, UINT32 size) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetBlob(&This->attributes.IMFAttributes_iface, key, buf, size); +} + +static HRESULT WINAPI mfbytestream_mfattributes_SetUnknown( + IMFAttributes *iface, REFGUID key, IUnknown *unknown) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_SetUnknown(&This->attributes.IMFAttributes_iface, key, unknown); +} + +static HRESULT WINAPI mfbytestream_mfattributes_LockStore(IMFAttributes *iface) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_LockStore(&This->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI mfbytestream_mfattributes_UnlockStore(IMFAttributes *iface) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_UnlockStore(&This->attributes.IMFAttributes_iface); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetCount(IMFAttributes *iface, UINT32 *items) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetCount(&This->attributes.IMFAttributes_iface, items); +} + +static HRESULT WINAPI mfbytestream_mfattributes_GetItemByIndex( + IMFAttributes *iface, UINT32 index, GUID *key, PROPVARIANT *value) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + return IMFAttributes_GetItemByIndex(&This->attributes.IMFAttributes_iface, index, key, value); +} + +static HRESULT WINAPI mfbytestream_mfattributes_CopyAllItems( + IMFAttributes *iface, IMFAttributes *dest) +{ + mfbytestream *This = impl_from_IMFByteStream_IMFAttributes(iface); + + FIXME("%p, %p\n", This, dest); + + return E_NOTIMPL; +} + +static const IMFAttributesVtbl mfbytestream_mfattributes_vtbl = +{ + mfbytestream_mfattributes_QueryInterface, + mfbytestream_mfattributes_AddRef, + mfbytestream_mfattributes_Release, + mfbytestream_mfattributes_GetItem, + mfbytestream_mfattributes_GetItemType, + mfbytestream_mfattributes_CompareItem, + mfbytestream_mfattributes_Compare, + mfbytestream_mfattributes_GetUINT32, + mfbytestream_mfattributes_GetUINT64, + mfbytestream_mfattributes_GetDouble, + mfbytestream_mfattributes_GetGUID, + mfbytestream_mfattributes_GetStringLength, + mfbytestream_mfattributes_GetString, + mfbytestream_mfattributes_GetAllocatedString, + mfbytestream_mfattributes_GetBlobSize, + mfbytestream_mfattributes_GetBlob, + mfbytestream_mfattributes_GetAllocatedBlob, + mfbytestream_mfattributes_GetUnknown, + mfbytestream_mfattributes_SetItem, + mfbytestream_mfattributes_DeleteItem, + mfbytestream_mfattributes_DeleteAllItems, + mfbytestream_mfattributes_SetUINT32, + mfbytestream_mfattributes_SetUINT64, + mfbytestream_mfattributes_SetDouble, + mfbytestream_mfattributes_SetGUID, + mfbytestream_mfattributes_SetString, + mfbytestream_mfattributes_SetBlob, + mfbytestream_mfattributes_SetUnknown, + mfbytestream_mfattributes_LockStore, + mfbytestream_mfattributes_UnlockStore, + mfbytestream_mfattributes_GetCount, + mfbytestream_mfattributes_GetItemByIndex, + mfbytestream_mfattributes_CopyAllItems +}; + HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream) { mfbytestream *object; @@ -1076,8 +1386,9 @@ HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **byt if(!object) return E_OUTOFMEMORY;
- object->ref = 1; - object->IMFByteStream_iface.lpVtbl = &mfbytesteam_vtbl; + init_attribute_object(&object->attributes, 0); + object->IMFByteStream_iface.lpVtbl = &mfbytestream_vtbl; + object->IMFAttributes_iface.lpVtbl = &mfbytestream_mfattributes_vtbl;
*bytestream = &object->IMFByteStream_iface;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 17cdc46579..4605e20f32 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -258,8 +258,12 @@ static void test_MFCreateAttributes(void) static void test_MFCreateMFByteStreamOnStream(void) { IMFByteStream *bytestream; + IMFByteStream *bytestream2; IStream *stream; + IMFAttributes *attributes = NULL; + IUnknown *unknown; HRESULT hr; + ULONG ref;
if(!pMFCreateMFByteStreamOnStream) { @@ -270,11 +274,56 @@ static void test_MFCreateMFByteStreamOnStream(void) hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); ok(hr == S_OK, "got 0x%08x\n", hr);
- hr = pMFCreateMFByteStreamOnStream(stream, &bytestream ); + hr = pMFCreateMFByteStreamOnStream(stream, &bytestream); ok(hr == S_OK, "got 0x%08x\n", hr);
- IStream_Release(stream); + hr = IUnknown_QueryInterface(bytestream, &IID_IUnknown, + (void **)&unknown); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok((void *)unknown == (void *)bytestream, "got %p\n", unknown); + ref = IUnknown_Release(unknown); + ok(ref == 1, "got %u\n", ref); + + hr = IUnknown_QueryInterface(unknown, &IID_IMFByteStream, + (void **)&bytestream2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(bytestream2 == bytestream, "got %p\n", bytestream2); + ref = IMFByteStream_Release(bytestream2); + ok(ref == 1, "got %u\n", ref); + + hr = IUnknown_QueryInterface(bytestream, &IID_IMFAttributes, + (void **)&attributes); + ok(hr == S_OK || + /* w7pro64 */ + broken(hr == E_NOINTERFACE), "got 0x%08x\n", hr); + + if (hr != S_OK) + { + win_skip("Can not retrieve IMFAttributes interface from IMFByteStream\n"); + IStream_Release(stream); + IMFByteStream_Release(bytestream); + return; + } + + ok(attributes != NULL, "got NULL\n"); + + hr = IUnknown_QueryInterface(attributes, &IID_IUnknown, + (void **)&unknown); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok((void *)unknown == (void *)bytestream, "got %p\n", unknown); + ref = IUnknown_Release(unknown); + ok(ref == 2, "got %u\n", ref); + + hr = IUnknown_QueryInterface(attributes, &IID_IMFByteStream, + (void **)&bytestream2); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(bytestream2 == bytestream, "got %p\n", bytestream2); + ref = IMFByteStream_Release(bytestream2); + ok(ref == 2, "got %u\n", ref); + + IMFAttributes_Release(attributes); IMFByteStream_Release(bytestream); + IStream_Release(stream); }
static void test_MFCreateMemoryBuffer(void)