Signed-off-by: Derek Lesho dlesho@codeweavers.com --- v3: - Rebase against 133ba763e1f419dc23fd58ac82c6d8a73014ae22. - Remove accidental inclusion of test.mp3. --- dlls/mf/tests/Makefile.in | 2 - dlls/mf/tests/mf.c | 601 +++++++++++++++++++++++++++++++------- dlls/mf/tests/resource.rc | 22 -- 3 files changed, 499 insertions(+), 126 deletions(-) delete mode 100644 dlls/mf/tests/resource.rc
diff --git a/dlls/mf/tests/Makefile.in b/dlls/mf/tests/Makefile.in index 5eb9ee4d4e3..614eb4fbc9e 100644 --- a/dlls/mf/tests/Makefile.in +++ b/dlls/mf/tests/Makefile.in @@ -3,5 +3,3 @@ IMPORTS = mf mfplat mfuuid ole32 user32
C_SRCS = \ mf.c - -RC_SRCS = resource.rc diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index fda80974724..092735466be 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -44,6 +44,7 @@ DEFINE_GUID(MFVideoFormat_ABGR32, 0x00000020, 0x0000, 0x0010, 0x80, 0x00, 0x00, #include "mmdeviceapi.h" #include "audioclient.h" #include "evr.h" +#include "propvarutil.h"
#include "wine/test.h"
@@ -97,34 +98,6 @@ static HWND create_window(void) 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); }
-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)) @@ -1447,26 +1420,316 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl = test_grabber_callback_OnShutdown, };
+struct test_source +{ + IMFMediaSource IMFMediaSource_iface; + LONG refcount; +}; + +static struct test_source *impl_from_IMFMediaSource(IMFMediaSource *iface) +{ + return CONTAINING_RECORD(iface, struct test_source, IMFMediaSource_iface); +} + +static HRESULT WINAPI test_source_QueryInterface(IMFMediaSource *iface, REFIID riid, void **out) +{ + if (IsEqualIID(riid, &IID_IMFMediaSource) + || IsEqualIID(riid, &IID_IMFMediaEventGenerator) + || IsEqualIID(riid, &IID_IUnknown)) + { + *out = iface; + } + else + { + *out = NULL; + return E_NOINTERFACE; + } + + IMFMediaSource_AddRef(iface); + return S_OK; +} + +static ULONG WINAPI test_source_AddRef(IMFMediaSource *iface) +{ + struct test_source *source = impl_from_IMFMediaSource(iface); + return InterlockedIncrement(&source->refcount); +} + +static ULONG WINAPI test_source_Release(IMFMediaSource *iface) +{ + struct test_source *source = impl_from_IMFMediaSource(iface); + ULONG refcount = InterlockedDecrement(&source->refcount); + + if (!refcount) + HeapFree(GetProcessHeap(), 0, source); + + return refcount; +} + +static HRESULT WINAPI test_source_GetEvent(IMFMediaSource *iface, DWORD flags, IMFMediaEvent **event) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_BeginGetEvent(IMFMediaSource *iface, IMFAsyncCallback *callback, IUnknown *state) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_EndGetEvent(IMFMediaSource *iface, IMFAsyncResult *result, IMFMediaEvent **event) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_QueueEvent(IMFMediaSource *iface, MediaEventType event_type, REFGUID ext_type, + HRESULT hr, const PROPVARIANT *value) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_GetCharacteristics(IMFMediaSource *iface, DWORD *flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_CreatePresentationDescriptor(IMFMediaSource *iface, IMFPresentationDescriptor **pd) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Start(IMFMediaSource *iface, IMFPresentationDescriptor *pd, const GUID *time_format, + const PROPVARIANT *start_position) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Stop(IMFMediaSource *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Pause(IMFMediaSource *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_source_Shutdown(IMFMediaSource *iface) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static const IMFMediaSourceVtbl test_source_vtbl = +{ + test_source_QueryInterface, + test_source_AddRef, + test_source_Release, + test_source_GetEvent, + test_source_BeginGetEvent, + test_source_EndGetEvent, + test_source_QueueEvent, + test_source_GetCharacteristics, + test_source_CreatePresentationDescriptor, + test_source_Start, + test_source_Stop, + test_source_Pause, + test_source_Shutdown, +}; + +static IMFMediaSource *create_test_source(void) +{ + struct test_source *source; + + source = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(*source)); + source->IMFMediaSource_iface.lpVtbl = &test_source_vtbl; + source->refcount = 1; + + return &source->IMFMediaSource_iface; +} + static void test_topology_loader(void) { + static const struct resolution_test + { + union + { + WAVEFORMATEX input_type; + MPEGLAYER3WAVEFORMAT mp3_input_type; + }; + WAVEFORMATEX output_type; + MF_CONNECT_METHOD method; + HRESULT expected_result; + BOOL expect_decoder, expect_converter, wine_todo; + } + resolution_tests[] = + { + { + .input_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = MF_CONNECT_DIRECT, + .expected_result = S_OK, + .expect_decoder = FALSE, + .expect_converter = FALSE, + .wine_todo = FALSE, + }, + { + .input_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 48000, + .nAvgBytesPerSec = 48000, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = MF_CONNECT_DIRECT, + .expected_result = MF_E_INVALIDMEDIATYPE, + .expect_decoder = FALSE, + .expect_converter = FALSE, + .wine_todo = FALSE, + }, + { + .input_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 48000, + .nAvgBytesPerSec = 48000, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = MF_CONNECT_ALLOW_CONVERTER, + .expected_result = S_OK, + .expect_decoder = FALSE, + .expect_converter = TRUE, + .wine_todo = TRUE, + }, + /* Test MF_TOPONODE_CONNECT_METHOD: + - 0x1 (MF_CONNECT_ALLOW_CONVERTER) allows converters + - 0x3 (MF_CONNECT_ALLOW_DECODER) allows converters and decoders + - 0x2 allows neither */ + { + .mp3_input_type = { + { + .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES, + }, + .wID = MPEGLAYER3_ID_MPEG, + .fdwFlags = 0, + .nBlockSize = 417, + .nFramesPerBlock = 0, + .nCodecDelay = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = MF_CONNECT_DIRECT, + .expected_result = MF_E_INVALIDMEDIATYPE, + .expect_decoder = FALSE, + .expect_converter = FALSE, + .wine_todo = TRUE, + }, + { + .mp3_input_type = { + { + .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES, + }, + .wID = MPEGLAYER3_ID_MPEG, + .fdwFlags = 0, + .nBlockSize = 417, + .nFramesPerBlock = 0, + .nCodecDelay = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 2, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = MF_CONNECT_ALLOW_CONVERTER, + .expected_result = MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION, + .expect_decoder = FALSE, + .expect_converter = FALSE, + .wine_todo = TRUE, + }, + { + .mp3_input_type = { + { + .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES, + }, + .wID = MPEGLAYER3_ID_MPEG, + .fdwFlags = 0, + .nBlockSize = 417, + .nFramesPerBlock = 0, + .nCodecDelay = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 2, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = 2, + .expected_result = MF_E_INVALIDMEDIATYPE, + .expect_decoder = FALSE, + .expect_converter = FALSE, + .wine_todo = TRUE, + }, + { + .mp3_input_type = { + { + .wFormatTag = WAVE_FORMAT_MPEGLAYER3, .nChannels = 2, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 16000, .nBlockAlign = 1, .wBitsPerSample = 0, .cbSize = MPEGLAYER3_WFX_EXTRA_BYTES, + }, + .wID = MPEGLAYER3_ID_MPEG, + .fdwFlags = 0, + .nBlockSize = 417, + .nFramesPerBlock = 0, + .nCodecDelay = 0, + }, + .output_type = { + .wFormatTag = WAVE_FORMAT_PCM, .nChannels = 1, .nSamplesPerSec = 44100, + .nAvgBytesPerSec = 44100, .nBlockAlign = 1, .wBitsPerSample = 8, .cbSize = 0, + }, + .method = MF_CONNECT_ALLOW_DECODER, + .expected_result = S_OK, + .expect_decoder = TRUE, + .expect_converter = FALSE, + .wine_todo = TRUE, + }, + }; + IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl }; + IMFTopologyNode *src_node, *sink_node, *src_node2, *sink_node2, *mft_node; IMFTopology *topology, *topology2, *full_topology; - IMFTopologyNode *src_node, *sink_node; + unsigned int count, value, index; IMFPresentationDescriptor *pd; - IMFSourceResolver *resolver; IMFActivate *sink_activate; IMFStreamSink *stream_sink; - unsigned int count, value; + MF_TOPOLOGY_TYPE node_type; IMFMediaType *media_type; IMFStreamDescriptor *sd; - MF_OBJECT_TYPE obj_type; + IMFTransform *transform; IMFMediaSource *source; IMFTopoLoader *loader; - IMFByteStream *stream; - IMFAttributes *attr; + IUnknown *node_object; + BOOL compare_result; IMFMediaSink *sink; - WCHAR *filename; - BOOL selected; + WORD node_count; + unsigned int i; + TOPOID node_id; HRESULT hr; GUID guid;
@@ -1487,44 +1750,41 @@ 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); + /* Add source node. */ + hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); + ok(hr == S_OK, "Failed to create topology node, hr %#x.\n", hr);
- filename = load_resource(L"test.wav"); + /* when a decoder is involved, windows requires this attribute to be present */ + source = create_test_source();
- 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); + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source); + ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr);
- IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attr); - IMFAttributes_SetString(attr, &MF_BYTESTREAM_CONTENT_TYPE, L"audio/wav"); - IMFAttributes_Release(attr); + IMFMediaSource_Release(source);
- 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 = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
- hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd); - ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr); - if (FAILED(hr)) - return; + 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); + ok(hr == S_OK, "Failed to set attribute, 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 = MFCreateStreamDescriptor(0, 1, &media_type, &sd); + ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\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_STREAM_DESCRIPTOR, (IUnknown *)sd); + ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr);
- hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_SOURCE, (IUnknown *)source); - ok(hr == S_OK, "Failed to set node source, hr %#x.\n", hr); + hr = MFCreatePresentationDescriptor(1, &sd, &pd); + ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n");
hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr);
- hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); - ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd); + IMFMediaType_Release(media_type);
hr = IMFTopology_AddNode(topology, src_node); ok(hr == S_OK, "Failed to add a node, hr %#x.\n", hr); @@ -1534,7 +1794,9 @@ todo_wine todo_wine ok(hr == MF_E_TOPO_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
- /* Add grabber sink. */ + hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); + ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr); + hr = MFCreateMediaType(&media_type); ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
@@ -1546,13 +1808,11 @@ todo_wine hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate); ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr);
- IMFMediaType_Release(media_type); - - hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); - ok(hr == S_OK, "Failed to create output node, hr %#x.\n", hr); - hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate); ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); + + IMFMediaType_Release(media_type); + hr = IMFTopology_AddNode(topology, sink_node); ok(hr == S_OK, "Failed to add sink node, hr %#x.\n", hr);
@@ -1567,55 +1827,192 @@ todo_wine hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); ok(hr == MF_E_TOPO_SINK_ACTIVATES_UNSUPPORTED, "Unexpected hr %#x.\n", hr);
- hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink); - ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(resolution_tests); i++) + { + IMFMediaType *input_type, *output_type; + IMFMediaTypeHandler *mth;
- hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + /* TODO: remove once MFInitMediaTypeFromWaveFormatEx gains support for non-zero cbSize */ + if(resolution_tests[i].wine_todo && !strcmp(winetest_platform, "wine")) + { + todo_wine ok(0, "Skipping test %u on wine.\n", i); + continue; + }
- hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink); - ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); + hr = MFCreateMediaType(&input_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
- IMFStreamSink_Release(stream_sink); + hr = MFInitMediaTypeFromWaveFormatEx(input_type, &resolution_tests[i].input_type, sizeof(WAVEFORMATEX) + resolution_tests[i].input_type.cbSize); + ok(hr == S_OK, "MFInitMediaTypeFromWaveFormatEx failed, 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); + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Failed to create 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 = MFInitMediaTypeFromWaveFormatEx(output_type, &resolution_tests[i].output_type, sizeof(WAVEFORMATEX) + resolution_tests[i].output_type.cbSize); + ok(hr == S_OK, "MFInitMediaTypeFromWaveFormatEx failed, 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); + hr = MFCreateStreamDescriptor(0, 1, &input_type, &sd); + ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n", hr);
- hr = IMFTopology_GetCount(full_topology, &count); - ok(hr == S_OK, "Failed to get attribute count, 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_SetCurrentMediaType(mth, input_type); + ok(hr == S_OK, "Failed to set current media type, hr %#x.\n", hr); + + IMFMediaTypeHandler_Release(mth); + + hr = MFCreatePresentationDescriptor(1, &sd, &pd); + ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr); + + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_PRESENTATION_DESCRIPTOR, (IUnknown *)pd); + ok(hr == S_OK, "Failed to set node pd, hr %#x.\n", hr); + + IMFPresentationDescriptor_Release(pd); + + hr = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr); + + IMFStreamDescriptor_Release(sd); + + hr = MFCreateSampleGrabberSinkActivate(output_type, &test_grabber_callback, &sink_activate); + ok(hr == S_OK, "Failed to create grabber sink, hr %#x.\n", hr); + + hr = IMFActivate_ActivateObject(sink_activate, &IID_IMFMediaSink, (void **)&sink); + ok(hr == S_OK, "Failed to activate, hr %#x.\n", hr); + + hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFMediaSink_Release(sink); + + hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink); + ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); + + IMFStreamSink_Release(stream_sink); + + hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, resolution_tests[i].method); + ok(hr == S_OK, "Failed to set connect method, 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); + + hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); +todo_wine_if(resolution_tests[i].wine_todo) + ok(hr == resolution_tests[i].expected_result, "Unexpected hr %#x on test %u.\n", hr, i); + ok(full_topology != topology, "Unexpected instance.\n"); + + if (resolution_tests[i].expected_result == S_OK && hr == S_OK) + { + hr = IMFTopology_GetCount(full_topology, &count); + ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr); todo_wine - ok(count == 1, "Unexpected count %u.\n", count); + ok(count == 1, "Unexpected count %u.\n", count);
- hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL); + hr = IMFTopology_GetItemByIndex(full_topology, 0, &guid, NULL); todo_wine { - ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr); - ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid)); + ok(hr == S_OK, "Failed to get attribute key, hr %#x.\n", hr); + ok(IsEqualGUID(&guid, &MF_TOPOLOGY_RESOLUTION_STATUS), "Unexpected key %s.\n", wine_dbgstr_guid(&guid)); } - value = 0xdeadbeef; - hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value); + value = 0xdeadbeef; + hr = IMFTopology_GetUINT32(full_topology, &MF_TOPOLOGY_RESOLUTION_STATUS, &value); 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); + 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); - ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); - ok(full_topology != topology2, "Unexpected instance.\n");
- IMFTopology_Release(topology2); - IMFTopology_Release(full_topology); + hr = IMFTopology_GetNodeCount(full_topology, &node_count); + ok(hr == S_OK, "Failed to get node count, hr %#x.\n", hr); + ok(node_count == 2 + resolution_tests[i].expect_decoder + resolution_tests[i].expect_converter, "Unexpected node count %u.\n", node_count); + + hr = IMFTopologyNode_GetTopoNodeID(src_node, &node_id); + ok(hr == S_OK, "Failed to get source node id, hr %#x.\n", hr); + + hr = IMFTopology_GetNodeByID(full_topology, node_id, &src_node2); + ok(hr == S_OK, "Failed to get source in resolved topology, hr %#x.\n", hr); + + hr = IMFTopologyNode_GetTopoNodeID(sink_node, &node_id); + ok(hr == S_OK, "Failed to get sink node id, hr %#x.\n", hr); + + hr = IMFTopology_GetNodeByID(full_topology, node_id, &sink_node2); + ok(hr == S_OK, "Failed to get sink in resolved topology, hr %#x.\n", hr); + + if (resolution_tests[i].expect_decoder || resolution_tests[i].expect_converter) + { + hr = IMFTopologyNode_GetOutput(src_node2, 0, &mft_node, &index); + ok(hr == S_OK, "Failed to get transform node in resolved topology, hr %#x.\n", hr); + ok(index == 0, "Unexpected stream index %u.\n", index); + + hr = IMFTopologyNode_GetNodeType(mft_node, &node_type); + ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#x.\n", hr); + ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u, expected MF_TOPOLOGY_TRANSFORM_NODE.\n", node_type); + + hr = IMFTopologyNode_GetObject(mft_node, &node_object); + ok(hr == S_OK, "Failed to get object of transform node, hr %#x.\n", hr); + + hr = IUnknown_QueryInterface(node_object, &IID_IMFTransform, (void**) &transform); + ok(hr == S_OK, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr); + IUnknown_Release(node_object); + + hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type); + ok(hr == S_OK, "Failed to get transform input type, hr %#x.\n", hr); + + hr = IMFMediaType_Compare(media_type, (IMFAttributes *)input_type, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &compare_result); + ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr); + ok(compare_result, "Input type of first transform doesn't match source node type.\n"); + + IMFTopologyNode_Release(mft_node); + IMFMediaType_Release(media_type); + IMFTransform_Release(transform); + + hr = IMFTopologyNode_GetInput(sink_node2, 0, &mft_node, &index); + ok(hr == S_OK, "Failed to get transform node in resolved topology, hr %#x.\n", hr); + ok(index == 0, "Unexpected stream index %u.\n", index); + + hr = IMFTopologyNode_GetNodeType(mft_node, &node_type); + ok(hr == S_OK, "Failed to get transform node type in resolved topology, hr %#x.\n", hr); + ok(node_type == MF_TOPOLOGY_TRANSFORM_NODE, "Unexpected node type %u, expected MF_TOPOLOGY_TRANSFORM_NODE.\n", node_type); + + hr = IMFTopologyNode_GetObject(mft_node, &node_object); + ok(hr == S_OK, "Failed to get object of transform node, hr %#x.\n", hr); + + hr = IUnknown_QueryInterface(node_object, &IID_IMFTransform, (void**) &transform); + ok(hr == S_OK, "Failed to get IMFTransform from transform node's object, hr %#x.\n", hr); + IUnknown_Release(node_object); + + hr = IMFTransform_GetOutputCurrentType(transform, 0, &media_type); + ok(hr == S_OK, "Failed to get transform output type, hr %#x.\n", hr); + + hr = IMFMediaType_Compare(media_type, (IMFAttributes *)output_type, MF_ATTRIBUTES_MATCH_ALL_ITEMS, &compare_result); + ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr); + ok(compare_result, "Output type of last transform doesn't match sink node type.\n"); + + IMFTopologyNode_Release(mft_node); + IMFMediaType_Release(media_type); + IMFTransform_Release(transform); + } + + IMFTopologyNode_Release(sink_node2); + + hr = IMFTopoLoader_Load(loader, full_topology, &topology2, NULL); + ok(hr == S_OK, "Failed to resolve topology, hr %#x.\n", hr); + ok(full_topology != topology2, "Unexpected instance.\n"); + + IMFTopology_Release(topology2); + IMFTopology_Release(full_topology); + } + + 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); + + IMFActivate_ShutdownObject(sink_activate); + IMFActivate_Release(sink_activate); + IMFMediaType_Release(input_type); + IMFMediaType_Release(output_type); + }
- IMFMediaSource_Release(source); - IMFSourceResolver_Release(resolver); - IMFByteStream_Release(stream); IMFTopoLoader_Release(loader);
hr = MFShutdown(); diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc deleted file mode 100644 index f54212a8c8f..00000000000 --- a/dlls/mf/tests/resource.rc +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2019 Nikolay Sivov for CodeWeavers - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "windef.h" - -/* @makedep: test.wav */ -test.wav RCDATA test.wav