[PATCH v5 1/8] mf/tests: Add tests for the topology loader.

Sergio Gómez Del Real sdelreal at codeweavers.com
Wed Apr 22 22:28:28 CDT 2020


Signed-off-by: Sergio Gómez Del Real <sdelreal at codeweavers.com>
---
 dlls/mf/tests/mf.c | 570 +++++++++++++++++++++++++++++++++++++++------
 1 file changed, 501 insertions(+), 69 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index ae9f58a4bc..72fad1c77e 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -32,6 +32,7 @@
 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0);
 DEFINE_GUID(MFVideoFormat_P208, 0x38303250, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
 DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, 0xaa, 0x00, 0x38, 0x9b, 0x71);
+DEFINE_GUID(MFAudioFormat_ZZZ, 0x20202020, 0x2020, 0x2020, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20);
 
 #undef INITGUID
 #include <guiddef.h>
@@ -54,34 +55,6 @@ static void _expect_ref(IUnknown* obj, ULONG expected_refcount, int line)
             expected_refcount);
 }
 
-static WCHAR *load_resource(const WCHAR *name)
-{
-    static WCHAR pathW[MAX_PATH];
-    DWORD written;
-    HANDLE file;
-    HRSRC res;
-    void *ptr;
-
-    GetTempPathW(ARRAY_SIZE(pathW), pathW);
-    lstrcatW(pathW, name);
-
-    file = CreateFileW(pathW, GENERIC_READ|GENERIC_WRITE, 0,
-                       NULL, CREATE_ALWAYS, 0, 0);
-    ok(file != INVALID_HANDLE_VALUE, "file creation failed, at %s, error %d\n",
-       wine_dbgstr_w(pathW), GetLastError());
-
-    res = FindResourceW(NULL, name, (LPCWSTR)RT_RCDATA);
-    ok(res != 0, "couldn't find resource\n");
-    ptr = LockResource(LoadResource(GetModuleHandleA(NULL), res));
-    WriteFile(file, ptr, SizeofResource(GetModuleHandleA(NULL), res),
-               &written, NULL);
-    ok(written == SizeofResource(GetModuleHandleA(NULL), res),
-       "couldn't write resource\n" );
-    CloseHandle(file);
-
-    return pathW;
-}
-
 static HRESULT WINAPI test_unk_QueryInterface(IUnknown *iface, REFIID riid, void **obj)
 {
     if (IsEqualIID(riid, &IID_IUnknown))
@@ -1303,27 +1276,367 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl =
     test_grabber_callback_OnShutdown,
 };
 
+static HRESULT WINAPI test_media_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out)
+{
+    if (IsEqualIID(riid, &IID_IMFMediaSource) ||
+        IsEqualIID(riid, &IID_IMFMediaEventGenerator) ||
+        IsEqualIID(riid, &IID_IUnknown))
+    {
+        *out = iface;
+        IUnknown_AddRef((IUnknown*)*out);
+        return S_OK;
+    }
+
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI test_media_source_AddRef(IMFMediaSource *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI test_media_source_Release(IMFMediaSource *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI test_media_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type,
+        HRESULT hr, const PROPVARIANT *value)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_GetCharacteristics(IMFMediaSource *iface, DWORD *characteristics)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **descriptor)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *descriptor,
+                                     const GUID *time_format, const PROPVARIANT *start_position)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_Stop(IMFMediaSource *iface)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_Pause(IMFMediaSource *iface)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_media_source_Shutdown(IMFMediaSource *iface)
+{
+    return S_OK;
+}
+
+static const IMFMediaSourceVtbl test_media_source_vtbl =
+{
+    test_media_source_QueryInterface,
+    test_media_source_AddRef,
+    test_media_source_Release,
+    test_media_source_GetEvent,
+    test_media_source_BeginGetEvent,
+    test_media_source_EndGetEvent,
+    test_media_source_QueueEvent,
+    test_media_source_GetCharacteristics,
+    test_media_source_CreatePresentationDescriptor,
+    test_media_source_Start,
+    test_media_source_Stop,
+    test_media_source_Pause,
+    test_media_source_Shutdown,
+};
+
+static HRESULT WINAPI test_mft_generic_QueryInterface(IMFTransform *iface, REFIID riid, void **out)
+{
+    if (IsEqualIID(riid, &IID_IUnknown) || IsEqualIID(riid, &IID_IMFTransform))
+    {
+        *out = iface;
+        IUnknown_AddRef((IUnknown*)*out);
+        return S_OK;
+    }
+
+    *out = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI test_mft_generic_AddRef(IMFTransform *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI test_mft_generic_Release(IMFTransform *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI test_mft_generic_GetStreamLimits(IMFTransform *iface, DWORD *inputmin, DWORD *inputmax, DWORD *outputmin, DWORD *outputmax)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetStreamCount(IMFTransform *iface, DWORD *input_streams, DWORD *output_streams)
+{
+    *input_streams = 1;
+    *output_streams = 1;
+    return S_OK;
+}
+
+static HRESULT WINAPI test_mft_generic_GetStreamIDs(IMFTransform *iface, DWORD inputidsize, DWORD *inputids, DWORD outputidsize, DWORD *outputids)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetInputStreamInfo(IMFTransform *iface, DWORD inputstream, MFT_INPUT_STREAM_INFO *streaminfo)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetOutputStreamInfo(IMFTransform *iface, DWORD outputstream, MFT_OUTPUT_STREAM_INFO *streaminfo)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetAttributes(IMFTransform *iface, IMFAttributes **attributes)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetInputStreamAttributes(IMFTransform *iface, DWORD inputstream, IMFAttributes **attributes)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetOutputStreamAttributes(IMFTransform *iface, DWORD outputstream, IMFAttributes **attributes)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_DeleteInputStream(IMFTransform *iface, DWORD streamid)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_AddInputStreams(IMFTransform *iface, DWORD num_streams, DWORD *streamids)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_conv_GetOutputAvailableType(IMFTransform *iface, DWORD id, DWORD index, IMFMediaType **type)
+{
+    static IMFMediaType *conv_out_type;
+
+    if (id != 0 || index != 0)
+        return MF_E_NO_MORE_TYPES;
+
+    MFCreateMediaType(&conv_out_type);
+    IMFMediaType_SetGUID(conv_out_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
+    IMFMediaType_SetGUID(conv_out_type, &MF_MT_SUBTYPE, &MFAudioFormat_ZZZ);
+    IMFMediaType_SetUINT32(conv_out_type, &MF_MT_AUDIO_NUM_CHANNELS, 1);
+    IMFMediaType_SetUINT32(conv_out_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 32000);
+
+    *type = conv_out_type;
+    return S_OK;
+}
+
+static HRESULT WINAPI test_mft_conv_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+{
+    UINT32 num_channels, sample;
+
+    IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &num_channels);
+    IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &sample);
+
+    if (num_channels == 2 && sample == 44100)
+        return S_OK;
+
+    return MF_E_INVALIDMEDIATYPE;
+}
+
+static HRESULT WINAPI test_mft_conv_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags)
+{
+    UINT32 num_channels, sample;
+
+    IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_NUM_CHANNELS, &num_channels);
+    IMFMediaType_GetUINT32(type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, &sample);
+
+    if (num_channels == 1 && sample == 32000)
+        return S_OK;
+
+    return MF_E_INVALIDMEDIATYPE;
+}
+
+static HRESULT WINAPI test_mft_conv_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_conv_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetInputStatus(IMFTransform *iface, DWORD inputstream, DWORD *flags)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_GetOutputStatus(IMFTransform *iface, DWORD *flags)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_ProcessEvent(IMFTransform *iface, DWORD inputstream, IMFMediaEvent *event)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE type, ULONG_PTR param)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_ProcessInput(IMFTransform *iface, DWORD inputstream, IMFSample *sample, DWORD flags)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI test_mft_generic_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD outbufcount, MFT_OUTPUT_DATA_BUFFER *outsamples, DWORD *status)
+{
+    return E_NOTIMPL;
+}
+
+static const IMFTransformVtbl test_mft_conv_vtbl =
+{
+    test_mft_generic_QueryInterface,
+    test_mft_generic_AddRef,
+    test_mft_generic_Release,
+    test_mft_generic_GetStreamLimits,
+    test_mft_generic_GetStreamCount,
+    test_mft_generic_GetStreamIDs,
+    test_mft_generic_GetInputStreamInfo,
+    test_mft_generic_GetOutputStreamInfo,
+    test_mft_generic_GetAttributes,
+    test_mft_generic_GetInputStreamAttributes,
+    test_mft_generic_GetOutputStreamAttributes,
+    test_mft_generic_DeleteInputStream,
+    test_mft_generic_AddInputStreams,
+    test_mft_generic_GetInputAvailableType,
+    test_mft_conv_GetOutputAvailableType,
+    test_mft_conv_SetInputType,
+    test_mft_conv_SetOutputType,
+    test_mft_conv_GetInputCurrentType,
+    test_mft_conv_GetOutputCurrentType,
+    test_mft_generic_GetInputStatus,
+    test_mft_generic_GetOutputStatus,
+    test_mft_generic_SetOutputBounds,
+    test_mft_generic_ProcessEvent,
+    test_mft_generic_ProcessMessage,
+    test_mft_generic_ProcessInput,
+    test_mft_generic_ProcessOutput,
+};
+
+static IMFTransform test_mft_conv = { &test_mft_conv_vtbl };
+
+static HRESULT WINAPI ClassFactory_QueryInterface(IClassFactory *iface, REFIID riid, void **ppv)
+{
+    if (IsEqualGUID(riid, &IID_IUnknown) || (IsEqualGUID(riid, &IID_IClassFactory))) {
+        *ppv = iface;
+        return S_OK;
+    }
+
+    *ppv = NULL;
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI ClassFactory_AddRef(IClassFactory *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI ClassFactory_Release(IClassFactory *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI ClassFactoryConv_CreateInstance(IClassFactory *iface,
+        IUnknown *pUnkOuter, REFIID riid, void **ppv)
+{
+    *ppv = &test_mft_conv;
+    return S_OK;
+}
+
+static HRESULT WINAPI ClassFactory_LockServer(IClassFactory *iface, BOOL fLock)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static const IClassFactoryVtbl ClassFactoryConvVtbl = {
+    ClassFactory_QueryInterface,
+    ClassFactory_AddRef,
+    ClassFactory_Release,
+    ClassFactoryConv_CreateInstance,
+    ClassFactory_LockServer
+};
+
+static IClassFactory ClassFactoryConv = { &ClassFactoryConvVtbl };
+
+static const CLSID test_conv_clsid =   { 0x12345678, 0x1234, 0x1234, { 0x12, 0x34, 0x56, 0x78, 0x9a, 0xbc, 0xde, 0xf0 } };
 static void test_topology_loader(void)
 {
     IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl };
-    IMFTopology *topology, *topology2, *full_topology;
+    IMFMediaSource test_media_source = { &test_media_source_vtbl };
+    IMFTopology *topology, *full_topology = NULL;
+    static WCHAR str[] = { 'c','o','n','v', 0 };
+    IMFMediaType *media_type, *mediatypes_pd[3];
     IMFTopologyNode *src_node, *sink_node;
+    MFT_REGISTER_TYPE_INFO typeinfo;
     IMFPresentationDescriptor *pd;
-    IMFSourceResolver *resolver;
     IMFActivate *sink_activate;
+    IMFStreamSink *stream_sink;
     unsigned int count, value;
-    IMFMediaType *media_type;
+    IMFMediaTypeHandler *mth;
     IMFStreamDescriptor *sd;
-    MF_OBJECT_TYPE obj_type;
-    IMFMediaSource *source;
     IMFTopoLoader *loader;
-    IMFByteStream *stream;
-    IMFAttributes *attr;
     IMFMediaSink *sink;
-    WCHAR *filename;
+    WORD node_count;
     BOOL selected;
     HRESULT hr;
     GUID guid;
+    DWORD reg;
 
     hr = MFStartup(MF_VERSION, MFSTARTUP_FULL);
     ok(hr == S_OK, "Startup failure, hr %#x.\n", hr);
@@ -1342,35 +1655,38 @@ static void test_topology_loader(void)
 todo_wine
     ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
 
-    hr = MFCreateSourceResolver(&resolver);
-    ok(hr == S_OK, "Failed to create source resolver, hr %#x.\n", hr);
-
-    filename = load_resource(L"test.wav");
-
-    hr = MFCreateFile(MF_ACCESSMODE_READ, MF_OPENMODE_FAIL_IF_NOT_EXIST, MF_FILEFLAGS_NONE, filename, &stream);
-    ok(hr == S_OK, "Failed to create file stream, hr %#x.\n", hr);
-
-    IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attr);
-    IMFAttributes_SetString(attr, &MF_BYTESTREAM_CONTENT_TYPE, L"audio/wav");
-    IMFAttributes_Release(attr);
-
-    hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL,
-            &obj_type, (IUnknown **)&source);
-    ok(hr == S_OK || broken(FAILED(hr)) /* Vista */, "Failed to create source, hr %#x.\n", hr);
-    if (FAILED(hr))
-        return;
-
-    hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
-    ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr);
-
-    hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
-    ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
+    hr = MFCreateMediaType(&mediatypes_pd[0]);
+    ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+    hr = IMFMediaType_SetGUID(mediatypes_pd[0], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
+    ok(hr == S_OK, "Failed to set GUID, hr %#x.\n", hr);
+    hr = IMFMediaType_SetGUID(mediatypes_pd[0], &MF_MT_SUBTYPE, &MFAudioFormat_ZZZ);
+    ok(hr == S_OK, "Failed to set GUID, hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(mediatypes_pd[0], &MF_MT_AUDIO_NUM_CHANNELS, 2);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(mediatypes_pd[0], &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+    hr = MFCreateMediaType(&mediatypes_pd[1]);
+    ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
+    hr = IMFMediaType_SetGUID(mediatypes_pd[1], &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
+    ok(hr == S_OK, "Failed to set GUID, hr %#x.\n", hr);
+    hr = IMFMediaType_SetGUID(mediatypes_pd[1], &MF_MT_SUBTYPE, &MFAudioFormat_ZZZ);
+    ok(hr == S_OK, "Failed to set GUID, hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(mediatypes_pd[1], &MF_MT_AUDIO_NUM_CHANNELS, 1);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(mediatypes_pd[1], &MF_MT_AUDIO_SAMPLES_PER_SECOND, 32000);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+    hr = MFCreateStreamDescriptor(0, 2, mediatypes_pd, &sd);
+    ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n", hr);
+    hr = MFCreatePresentationDescriptor(1, &sd, &pd);
+    ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr);
+    hr = IMFPresentationDescriptor_SelectStream(pd, 0);
+    ok(hr == S_OK, "Failed selecting stream.\n");
 
     /* Add source node. */
     hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
     ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
 
-    hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source);
+    hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)&test_media_source);
     ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
 
     hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd);
@@ -1393,7 +1709,11 @@ todo_wine
 
     hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio);
     ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
-    hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM);
+    hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_ZZZ);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_NUM_CHANNELS, 1);
+    ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
+    hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 32000);
     ok(hr == S_OK, "Failed to set attribute, hr %#x.\n", hr);
 
     hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate);
@@ -1423,22 +1743,49 @@ todo_wine
     hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink);
     ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr);
 
-    hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink);
+    hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink);
+    ok(hr == S_OK, "Failed to get stream sink, hr %#x.\n", hr);
+
+    hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink);
     ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr);
 
     hr = IMFTopology_GetCount(topology, &count);
     ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
     ok(count == 0, "Unexpected count %u.\n", count);
 
+    /* if no current media type set, loader uses first index exclusively */
     hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
 todo_wine
+    ok(hr == MF_E_TOPO_CODEC_NOT_FOUND, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &mth);
+    ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 0, &media_type);
+    ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr);
+
+    /* setting current media type overrides previous behavior; tries with it, and only with it */
+    hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type);
+    ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr);
+
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
+todo_wine
+    ok(hr == MF_E_TOPO_CODEC_NOT_FOUND, "Unexpected hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 1, &media_type);
+    ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type);
+    ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr);
+
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
     ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
-    ok(full_topology != topology, "Unexpected instance.\n");
 
     hr = IMFTopology_GetCount(topology, &count);
     ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
     ok(count == 0, "Unexpected count %u.\n", count);
 
+    hr = E_FAIL;
     hr = IMFTopology_GetCount(full_topology, &count);
     ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr);
 todo_wine
@@ -1455,16 +1802,101 @@ todo_wine {
     ok(hr == S_OK, "Failed to get attribute, hr %#x.\n", hr);
     ok(value == MF_TOPOLOGY_RESOLUTION_SUCCEEDED, "Unexpected value %#x.\n", value);
 }
-    hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL);
+
+    IMFTopology_Release(full_topology);
+  
+    /* test with stream deselected */
+    hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
+    ok(hr == S_OK, "Failed getting stream descriptor, hr %#x.\n", hr);
+ 
+    hr = IMFPresentationDescriptor_DeselectStream(pd, 0);
+    ok(hr == S_OK, "Failed deselecting stream, hr %#x.\n", hr);
+ 
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
     ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
-    ok(full_topology != topology2, "Unexpected instance.\n");
+ 
+    IMFPresentationDescriptor_Release(pd);
+    IMFStreamDescriptor_Release(sd);
+    IMFTopologyNode_Release(src_node);
+ 
+    hr = IMFTopology_GetNode(full_topology, 0, &src_node);
+    ok(hr == S_OK, "Failed to get source node, hr %#x.\n", hr);
+    hr = IMFTopologyNode_GetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, &IID_IMFPresentationDescriptor, (void **)&pd);
+    ok(hr == S_OK, "Failed to get presentation descriptor, hr %#x.\n", hr);
+    hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
+    ok(hr == S_OK, "Failed to get stream descriptor, hr %#x.\n", hr);
+    ok(!selected, "Stream should not be selected.\n");
+ 
+    IMFStreamDescriptor_Release(sd);
+    IMFTopologyNode_Release(src_node);
+    IMFPresentationDescriptor_Release(pd);
+    IMFTopology_Release(full_topology);
+
+    /* register a converter to test source -> mft -> sink */
+    hr = CoRegisterClassObject(&test_conv_clsid, (IUnknown*)&ClassFactoryConv, CLSCTX_INPROC_SERVER, REGCLS_MULTIPLEUSE, &reg);
+    ok(hr == S_OK, "Failed to register class object, hr %#x.\n");
+
+    typeinfo.guidMajorType = MFMediaType_Audio;
+    typeinfo.guidSubtype = MFAudioFormat_ZZZ;
+    hr = MFTRegisterLocalByCLSID(&test_conv_clsid, &MFT_CATEGORY_AUDIO_DECODER, str, MFT_ENUM_FLAG_ASYNCMFT, 1, &typeinfo, 1, &typeinfo);
+    ok(hr == S_OK, "Failed to register mft, hr %#x.\n");
+
+    hr = IMFTopology_GetNode(topology, 0, &src_node);
+    ok(hr == S_OK, "Failed to get source node, hr %#x.\n", hr);
 
-    IMFTopology_Release(topology2);
+    hr = IMFMediaTypeHandler_GetMediaTypeByIndex(mth, 0, &media_type);
+    ok(hr == S_OK, "Failed getting media type, hr %#x.\n", hr);
+
+    hr = IMFMediaTypeHandler_SetCurrentMediaType(mth, media_type);
+    ok(hr == S_OK, "Failed setting current media type, hr %#x.\n", hr);
+
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
+    ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
+    hr = IMFTopology_GetNodeCount(full_topology, &node_count);
+    ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
+todo_wine
+    ok(node_count == 3, "Unexpected node count %d.\n", node_count);
     IMFTopology_Release(full_topology);
 
-    IMFMediaSource_Release(source);
-    IMFSourceResolver_Release(resolver);
-    IMFByteStream_Release(stream);
+    /* test when MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES attribute is set on topology */
+    hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, 1);
+    ok(hr == S_OK, "Failed to set attribute.\n");
+
+    /* test with MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES set on source */
+    hr = IMFTopologyNode_SetUINT32(src_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES);
+    ok(hr == S_OK, "Failed to set attribute.\n");
+
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
+    ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
+
+    hr = IMFTopology_GetNodeCount(full_topology, &node_count);
+    ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
+todo_wine
+    ok(node_count == 3, "Unexpected node count %d.\n", node_count);
+
+    /* now test without MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES on source */
+    hr = IMFTopologyNode_SetUINT32(src_node, &MF_TOPONODE_CONNECT_METHOD, ~MF_CONNECT_RESOLVE_INDEPENDENT_OUTPUTTYPES);
+    ok(hr == S_OK, "Failed to set attribute.\n");
+
+    IMFTopology_Release(full_topology);
+    hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL);
+    ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr);
+    hr = IMFTopology_GetNodeCount(full_topology, &node_count);
+    ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr);
+    ok(node_count == 2, "Unexpected node count %d.\n", node_count);
+    IMFTopology_Release(full_topology);
+
+    IMFMediaType_Release(mediatypes_pd[0]);
+    IMFMediaType_Release(mediatypes_pd[1]);
+    IMFStreamDescriptor_Release(sd);
+    IMFPresentationDescriptor_Release(pd);
+    IMFTopology_RemoveNode(topology, src_node);
+
+    hr = MFTUnregister(test_conv_clsid);
+    ok(hr == S_OK, "Failed to unregister mft, hr %#x.\n");
+    hr = CoRevokeClassObject(reg);
+    ok(hr == S_OK, "Failed to unregister class object, hr %#x.\n");
+
     IMFTopoLoader_Release(loader);
 
     hr = MFShutdown();
-- 
2.17.1




More information about the wine-devel mailing list