Signed-off-by: Jactry Zeng jzeng@codeweavers.com --- dlls/mfplat/main.c | 189 ++++++++++++++++++++++++++++++++++++- dlls/mfplat/tests/mfplat.c | 11 +++ 2 files changed, 198 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index c7c346512f..9497e304cd 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -849,6 +849,8 @@ typedef struct _mfbytestream { mfattributes attributes; IMFByteStream IMFByteStream_iface; + + IStream *stream; } mfbytestream;
static inline mfbytestream *impl_from_IMFByteStream(IMFByteStream *iface) @@ -1070,6 +1072,182 @@ static const IMFByteStreamVtbl mfbytestream_vtbl = mfbytestream_Close };
+static ULONG WINAPI stream_mfbytestream_Release(IMFByteStream *iface) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + ULONG ref = InterlockedDecrement(&This->attributes.ref); + + TRACE("(%p) ref=%u\n", This, ref); + + if(!ref) + { + IStream_Release(This->stream); + heap_free(This); + } + + return ref; +} + +static HRESULT WINAPI stream_mfbytestream_GetCapabilities(IMFByteStream *iface, DWORD *capabilities) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p)\n", This, capabilities); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_GetLength(IMFByteStream *iface, QWORD *length) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p)\n", This, length); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_SetLength(IMFByteStream *iface, QWORD length) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(length)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_GetCurrentPosition(IMFByteStream *iface, QWORD *position) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p)\n", This, position); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_SetCurrentPosition(IMFByteStream *iface, QWORD position) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%s)\n", This, wine_dbgstr_longlong(position)); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_IsEndOfStream(IMFByteStream *iface, BOOL *endstream) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p)\n", This, endstream); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_Read(IMFByteStream *iface, BYTE *data, ULONG count, ULONG *byte_read) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p, %u, %p)\n", This, data, count, byte_read); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_BeginRead(IMFByteStream *iface, BYTE *data, ULONG count, + IMFAsyncCallback *callback, IUnknown *state) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p, %u, %p, %p)\n", This, data, count, callback, state); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_EndRead(IMFByteStream *iface, IMFAsyncResult *result, ULONG *byte_read) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p, %p)\n", This, result, byte_read); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_Write(IMFByteStream *iface, const BYTE *data, ULONG count, ULONG *written) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p, %u, %p)\n", This, data, count, written); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_BeginWrite(IMFByteStream *iface, const BYTE *data, ULONG count, + IMFAsyncCallback *callback, IUnknown *state) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p, %u, %p, %p)\n", This, data, count, callback, state); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_EndWrite(IMFByteStream *iface, IMFAsyncResult *result, ULONG *written) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%p, %p)\n", This, result, written); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_Seek(IMFByteStream *iface, MFBYTESTREAM_SEEK_ORIGIN seek, + LONGLONG offset, DWORD flags, QWORD *current) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)->(%u, %s, 0x%08x, %p)\n", This, seek, wine_dbgstr_longlong(offset), flags, current); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_Flush(IMFByteStream *iface) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI stream_mfbytestream_Close(IMFByteStream *iface) +{ + mfbytestream *This = impl_from_IMFByteStream(iface); + + FIXME("(%p)\n", This); + + return E_NOTIMPL; +} + +static const IMFByteStreamVtbl stream_mfbytestream_vtbl = +{ + mfbytestream_QueryInterface, + mfbytestream_AddRef, + stream_mfbytestream_Release, + stream_mfbytestream_GetCapabilities, + stream_mfbytestream_GetLength, + stream_mfbytestream_SetLength, + stream_mfbytestream_GetCurrentPosition, + stream_mfbytestream_SetCurrentPosition, + stream_mfbytestream_IsEndOfStream, + stream_mfbytestream_Read, + stream_mfbytestream_BeginRead, + stream_mfbytestream_EndRead, + stream_mfbytestream_Write, + stream_mfbytestream_BeginWrite, + stream_mfbytestream_EndWrite, + stream_mfbytestream_Seek, + stream_mfbytestream_Flush, + stream_mfbytestream_Close +}; + static inline mfbytestream *impl_from_IMFByteStream_IMFAttributes(IMFAttributes *iface) { return CONTAINING_RECORD(iface, mfbytestream, attributes.IMFAttributes_iface); @@ -1134,16 +1312,23 @@ static const IMFAttributesVtbl mfbytestream_attributes_vtbl = HRESULT WINAPI MFCreateMFByteStreamOnStream(IStream *stream, IMFByteStream **bytestream) { mfbytestream *object; + HRESULT hr;
- TRACE("(%p, %p): stub\n", stream, bytestream); + TRACE("(%p, %p)\n", stream, bytestream);
object = heap_alloc( sizeof(*object) ); if(!object) return E_OUTOFMEMORY;
init_attribute_object(&object->attributes, 0); - object->IMFByteStream_iface.lpVtbl = &mfbytestream_vtbl; + object->IMFByteStream_iface.lpVtbl = &stream_mfbytestream_vtbl; object->attributes.IMFAttributes_iface.lpVtbl = &mfbytestream_attributes_vtbl; + hr = IStream_QueryInterface(stream, &IID_IStream, (void **)&object->stream); + if(FAILED(hr)) + { + heap_free(object); + return hr; + }
*bytestream = &object->IMFByteStream_iface;
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 3fa59f4816..0ccc680aca 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -54,6 +54,15 @@ DEFINE_GUID(DUMMY_GUID2, 0x12345678,0x1234,0x1234,0x22,0x22,0x22,0x22,0x22,0x22,
static const WCHAR mp4file[] = {'t','e','s','t','.','m','p','4',0};
+#define CHECK_REF(obj,ref) _check_ref((IUnknown*)obj, ref, __LINE__) +static void _check_ref(IUnknown* obj, ULONG ref, int line) +{ + ULONG rc; + IUnknown_AddRef(obj); + rc = IUnknown_Release(obj); + ok_(__FILE__,line)(rc == ref, "expected refcount %d, got %d\n", ref, rc); +} + static WCHAR *load_resource(const WCHAR *name) { static WCHAR pathW[MAX_PATH]; @@ -450,8 +459,10 @@ static void test_MFCreateMFByteStreamOnStream(void) hr = CreateStreamOnHGlobal(NULL, TRUE, &stream); ok(hr == S_OK, "got 0x%08x\n", hr);
+ CHECK_REF(stream, 1); hr = pMFCreateMFByteStreamOnStream(stream, &bytestream); ok(hr == S_OK, "got 0x%08x\n", hr); + CHECK_REF(stream, 2);
hr = IMFByteStream_QueryInterface(bytestream, &IID_IUnknown, (void **)&unknown);