Signed-off-by: Sven Baars sven.wine@gmail.com --- dlls/mfplat/main.c | 184 +++++++++++++++++++++++++++++++++++++ dlls/mfplat/tests/mfplat.c | 37 +++++++- include/mfidl.idl | 47 ++++++++++ 3 files changed, 266 insertions(+), 2 deletions(-)
diff --git a/dlls/mfplat/main.c b/dlls/mfplat/main.c index e7e7e30b3d..3affc885cf 100644 --- a/dlls/mfplat/main.c +++ b/dlls/mfplat/main.c @@ -1208,6 +1208,174 @@ HRESULT WINAPI MFCreateAttributes(IMFAttributes **attributes, UINT32 size) return S_OK; }
+typedef struct _mfsource +{ + IMFMediaSource IMFMediaSource_iface; + LONG ref; +} mfsource; + +static inline mfsource *impl_from_IMFMediaSource(IMFMediaSource *iface) +{ + return CONTAINING_RECORD(iface, mfsource, IMFMediaSource_iface); +} + +static HRESULT WINAPI mfsource_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), out); + + if (IsEqualIID(riid, &IID_IMFMediaSource) || + IsEqualIID(riid, &IID_IMFMediaEventGenerator) || + IsEqualIID(riid, &IID_IUnknown)) + { + *out = &This->IMFMediaSource_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 mfsource_AddRef(IMFMediaSource *iface) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + ULONG ref = InterlockedIncrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + return ref; +} + +static ULONG WINAPI mfsource_Release(IMFMediaSource *iface) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + ULONG ref = InterlockedDecrement(&This->ref); + + TRACE("(%p) ref=%u\n", This, ref); + + if (!ref) + { + HeapFree(GetProcessHeap(), 0, This); + } + + return ref; +} + +static HRESULT WINAPI mfsource_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%#x, %p)\n", This, flags, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%p, %p)\n", This, callback, state); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%p, %p)\n", This, result, event); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type, + HRESULT hr, const PROPVARIANT *value) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%d, %s, %#x, %p)\n", This, event_type, debugstr_guid(ext_type), hr, value); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_GetCharacteristics(IMFMediaSource *iface, DWORD *characteristics) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%p): stub\n", This, characteristics); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%p): stub\n", This, descriptor); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor, + const GUID *time_format, const PROPVARIANT *start_position) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p)->(%p, %p, %p): stub\n", This, descriptor, time_format, start_position); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_Stop(IMFMediaSource *iface) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p): stub\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_Pause(IMFMediaSource *iface) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p): stub\n", This); + + return E_NOTIMPL; +} + +static HRESULT WINAPI mfsource_Shutdown(IMFMediaSource *iface) +{ + mfsource *This = impl_from_IMFMediaSource(iface); + + FIXME("(%p): stub\n", This); + + return S_OK; +} + +static const IMFMediaSourceVtbl mfsourcevtbl = +{ + mfsource_QueryInterface, + mfsource_AddRef, + mfsource_Release, + mfsource_GetEvent, + mfsource_BeginGetEvent, + mfsource_EndGetEvent, + mfsource_QueueEvent, + mfsource_GetCharacteristics, + mfsource_CreatePresentationDescriptor, + mfsource_Start, + mfsource_Stop, + mfsource_Pause, + mfsource_Shutdown, +}; + typedef struct _mfsourceresolver { IMFSourceResolver IMFSourceResolver_iface; @@ -1281,6 +1449,22 @@ static HRESULT WINAPI mfsourceresolver_CreateObjectFromByteStream(IMFSourceResol
FIXME("(%p)->(%p, %s, %#x, %p, %p, %p): stub\n", This, stream, debugstr_w(url), flags, props, obj_type, object);
+ if (flags & MF_RESOLUTION_MEDIASOURCE) + { + mfsource *new_object; + + new_object = HeapAlloc( GetProcessHeap(), 0, sizeof(*object) ); + if (!new_object) + return E_OUTOFMEMORY; + + new_object->IMFMediaSource_iface.lpVtbl = &mfsourcevtbl; + new_object->ref = 1; + + *object = (IUnknown *)&new_object->IMFMediaSource_iface; + *obj_type = MF_OBJECT_MEDIASOURCE; + return S_OK; + } + return E_NOTIMPL; }
diff --git a/dlls/mfplat/tests/mfplat.c b/dlls/mfplat/tests/mfplat.c index 97fca67be6..64f95d5aec 100644 --- a/dlls/mfplat/tests/mfplat.c +++ b/dlls/mfplat/tests/mfplat.c @@ -40,6 +40,7 @@ static HRESULT (WINAPI *pMFCreateSourceResolver)(IMFSourceResolver **resolver); static HRESULT (WINAPI *pMFCreateMFByteStreamOnStream)(IStream *stream, IMFByteStream **bytestream); static HRESULT (WINAPI *pMFCreateMemoryBuffer)(DWORD max_length, IMFMediaBuffer **buffer);
+DEFINE_GUID(MF_BYTESTREAM_CONTENT_TYPE, 0xfc358289,0x3cb6,0x460c,0xa4,0x24,0xb6,0x68,0x12,0x60,0x37,0x5a);
DEFINE_GUID(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS, 0xa634a91c, 0x822b, 0x41b9, 0xa4, 0x94, 0x4d, 0xe4, 0x64, 0x36, 0x12, 0xb0);
@@ -199,6 +200,10 @@ if(0) static void test_source_resolver(void) { IMFSourceResolver *resolver, *resolver2; + IMFByteStream *bytestream; + IMFAttributes *attributes; + IMFMediaSource *mediasource; + MF_OBJECT_TYPE obj_type; HRESULT hr; WCHAR *filename;
@@ -226,8 +231,36 @@ static void test_source_resolver(void) ok(hr == S_OK, "got %#x\n", hr); ok(resolver != resolver2, "Expected new instance\n");
- IMFSourceResolver_Release(resolver); IMFSourceResolver_Release(resolver2); + + filename = load_resource(mp4file); + + hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, + MF_FILEFLAGS_NONE, filename, &bytestream); + ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IUnknown_QueryInterface(bytestream, &IID_IMFAttributes, + (void **)&attributes); + ok(hr == S_OK, "got 0x%08x\n", hr); + hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, file_type); + todo_wine ok(hr == S_OK, "got 0x%08x\n", hr); + + hr = IMFSourceResolver_CreateObjectFromByteStream( + resolver, bytestream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, + &obj_type, (IUnknown **)&mediasource); + ok(hr == S_OK, "got 0x%08x\n", hr); + ok(mediasource != NULL, "got %p\n", mediasource); + ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type); + + IMFMediaSource_Release(mediasource); + IMFAttributes_Release(attributes); + IMFByteStream_Release(bytestream); + + IMFSourceResolver_Release(resolver); + + MFShutdown(); + + DeleteFileW(filename); }
static void init_functions(void) @@ -481,13 +514,13 @@ START_TEST(mfplat) init_functions();
test_register(); - test_source_resolver(); test_MFCreateMediaType(); test_MFCreateAttributes(); test_MFSample(); test_MFCreateFile(); test_MFCreateMFByteStreamOnStream(); test_MFCreateMemoryBuffer(); + test_source_resolver();
CoUninitialize(); } diff --git a/include/mfidl.idl b/include/mfidl.idl index 84be055d09..ac5acc50f5 100644 --- a/include/mfidl.idl +++ b/include/mfidl.idl @@ -212,6 +212,53 @@ interface IMFStreamDescriptor : IMFAttributes HRESULT GetMediaTypeHandler([out] IMFMediaTypeHandler **handler); }
+[ + object, + uuid(03cb2711-24d7-4db6-a17f-f3a7a479a536), +] +interface IMFPresentationDescriptor : IMFAttributes +{ + HRESULT GetStreamDescriptorCount([out] DWORD *pdwDescriptorCount); + HRESULT GetStreamDescriptorByIndex([in] DWORD dwIndex, [out] BOOL *pfSelected, [out] IMFStreamDescriptor **ppDescriptor); + HRESULT SelectStream([in] DWORD dwDescriptorIndex); + HRESULT DeselectStream([in] DWORD dwDescriptorIndex); + HRESULT Clone([out] IMFPresentationDescriptor **ppPresentationDescriptor); +} + +[ + object, + uuid(279a808d-aec7-40c8-9c6b-a6b492c78a66), +] +interface IMFMediaSource : IMFMediaEventGenerator +{ + HRESULT GetCharacteristics([out] DWORD *pdwCharacteristics); + + [local] + HRESULT CreatePresentationDescriptor([out] IMFPresentationDescriptor **ppPresentationDescriptor); + [call_as(CreatePresentationDescriptor)] + HRESULT RemoteCreatePresentationDescriptor( + [out] DWORD *pcbPD, + [out, size_is(,*pcbPD)] BYTE **pbPD, + [out] IMFPresentationDescriptor **ppRemotePD); + + HRESULT Start( + [in] IMFPresentationDescriptor *pPresentationDescriptor, + [in, unique] const GUID *pguidTimeFormat, + [in, unique] const PROPVARIANT *pvarStartPosition); + + HRESULT Stop(); + HRESULT Pause(); + HRESULT Shutdown(); +} + +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") +cpp_quote("#define MF_RESOLUTION_KEEP_BYTE_STREAM_ALIVE_ON_FAIL 0x00000020") +cpp_quote("#define MF_RESOLUTION_READ 0x00010000") +cpp_quote("#define MF_RESOLUTION_WRITE 0x00020000") +cpp_quote("#define MF_RESOLUTION_DISABLE_LOCAL_PLUGINS 0x00000040") + [ object, uuid(f6696e82-74f7-4f3d-a178-8a5e09c3659f)