From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/tests/Makefile.in | 2 - dlls/mf/tests/mf.c | 705 ++++++++++++++++++++++++++++++++------ dlls/mf/tests/resource.rc | 22 -- dlls/mf/tests/test.wav | Bin 4488 -> 0 bytes 4 files changed, 597 insertions(+), 132 deletions(-) delete mode 100644 dlls/mf/tests/resource.rc delete mode 100644 dlls/mf/tests/test.wav
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..5e5c30ec6fc 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -97,34 +97,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,28 +1419,458 @@ 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; +} + +struct type_attr +{ + const GUID *key; + unsigned int value; +}; + +static void init_media_type(IMFMediaType *mediatype, const GUID *major, const struct type_attr *attrs) +{ + HRESULT hr; + + hr = IMFMediaType_DeleteAllItems(mediatype); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = IMFMediaType_SetGUID(mediatype, &MF_MT_MAJOR_TYPE, major); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + while (attrs->key) + { + if (IsEqualGUID(attrs->key, &MF_MT_SUBTYPE)) + { + GUID subtype; + + memcpy(&subtype, IsEqualGUID(major, &MFMediaType_Audio) ? &MFAudioFormat_Base : &MFVideoFormat_Base, + sizeof(subtype)); + subtype.Data1 = attrs->value; + hr = IMFMediaType_SetGUID(mediatype, attrs->key, &subtype); + } + else + hr = IMFMediaType_SetUINT32(mediatype, attrs->key, attrs->value); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + attrs++; + } +} + +static void init_source_node(IMFMediaType *mediatype, IMFMediaSource *source, IMFTopologyNode *node) +{ + IMFPresentationDescriptor *pd; + IMFMediaTypeHandler *handler; + IMFStreamDescriptor *sd; + HRESULT hr; + + hr = IMFTopologyNode_DeleteAllItems(node); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + hr = MFCreateStreamDescriptor(0, 1, &mediatype, &sd); + ok(hr == S_OK, "Failed to create stream descriptor, hr %#x.\n", hr); + + hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, &handler); + ok(hr == S_OK, "Failed to get media type handler, hr %#x.\n", hr); + + hr = IMFMediaTypeHandler_SetCurrentMediaType(handler, mediatype); + ok(hr == S_OK, "Failed to set current media type, hr %#x.\n", hr); + + IMFMediaTypeHandler_Release(handler); + + hr = MFCreatePresentationDescriptor(1, &sd, &pd); + ok(hr == S_OK, "Failed to create presentation descriptor, hr %#x.\n", hr); + + hr = IMFTopologyNode_SetUnknown(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(node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + ok(hr == S_OK, "Failed to set node sd, hr %#x.\n", hr); + + hr = IMFTopologyNode_SetUnknown(node, &MF_TOPONODE_SOURCE, (IUnknown *)source); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFStreamDescriptor_Release(sd); +} + +static void init_sink_node(IMFActivate *sink_activate, unsigned int method, IMFTopologyNode *node) +{ + IMFStreamSink *stream_sink; + IMFMediaSink *sink; + HRESULT hr; + + hr = IMFTopologyNode_DeleteAllItems(node); + ok(hr == S_OK, "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); + + hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); + ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + + IMFMediaSink_Release(sink); + + hr = IMFTopologyNode_SetObject(node, (IUnknown *)stream_sink); + ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); + + IMFStreamSink_Release(stream_sink); + + hr = IMFTopologyNode_SetUINT32(node, &MF_TOPONODE_CONNECT_METHOD, method); + ok(hr == S_OK, "Failed to set connect method, hr %#x.\n", hr); +} + +enum loader_test_flags +{ + LOADER_EXPECTED_DECODER = 0x1, + LOADER_EXPECTED_CONVERTER = 0x2, + LOADER_TODO = 0x4, +}; + static void test_topology_loader(void) { + static const struct loader_test + { + const GUID *major; + struct + { + struct type_attr attrs[8]; + } input_type; + struct + { + struct type_attr attrs[8]; + } output_type; + + MF_CONNECT_METHOD method; + HRESULT expected_result; + unsigned int flags; + } + loader_tests[] = + { + { + /* PCM -> PCM, same type */ + &MFMediaType_Audio, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + + MF_CONNECT_DIRECT, + S_OK, + }, + + { + /* PCM -> PCM, different bps. */ + &MFMediaType_Audio, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + + MF_CONNECT_DIRECT, + MF_E_INVALIDMEDIATYPE, + LOADER_TODO, + }, + + { + /* PCM -> PCM, different bps. */ + &MFMediaType_Audio, + /* Source type */ + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + /* Sink type */ + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 48000 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 48000 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + + MF_CONNECT_ALLOW_CONVERTER, + S_OK, + LOADER_EXPECTED_CONVERTER, + }, + + { + /* MP3 -> PCM */ + &MFMediaType_Audio, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 }, + { &MF_MT_AUDIO_NUM_CHANNELS, 2 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + } + }, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + + MF_CONNECT_DIRECT, + MF_E_INVALIDMEDIATYPE, + LOADER_TODO, + }, + + { + /* MP3 -> PCM */ + &MFMediaType_Audio, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 }, + { &MF_MT_AUDIO_NUM_CHANNELS, 2 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + } + }, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + + MF_CONNECT_ALLOW_CONVERTER, + MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION, + LOADER_TODO, + }, + + { + /* MP3 -> PCM */ + &MFMediaType_Audio, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_MPEGLAYER3 }, + { &MF_MT_AUDIO_NUM_CHANNELS, 2 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 16000 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + } + }, + { + { + { &MF_MT_SUBTYPE, WAVE_FORMAT_PCM }, + { &MF_MT_AUDIO_NUM_CHANNELS, 1 }, + { &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_AVG_BYTES_PER_SECOND, 44100 }, + { &MF_MT_AUDIO_BLOCK_ALIGNMENT, 1 }, + { &MF_MT_AUDIO_BITS_PER_SAMPLE, 8 }, + } + }, + + MF_CONNECT_ALLOW_DECODER, + S_OK, + LOADER_EXPECTED_DECODER, + }, + }; + 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; + IMFMediaType *media_type, *input_type, *output_type; + unsigned int i, count, value, index; IMFPresentationDescriptor *pd; - IMFSourceResolver *resolver; IMFActivate *sink_activate; - IMFStreamSink *stream_sink; - unsigned int count, value; - IMFMediaType *media_type; + MF_TOPOLOGY_TYPE node_type; IMFStreamDescriptor *sd; - MF_OBJECT_TYPE obj_type; + IMFTransform *transform; IMFMediaSource *source; IMFTopoLoader *loader; - IMFByteStream *stream; - IMFAttributes *attr; - IMFMediaSink *sink; - WCHAR *filename; - BOOL selected; + IUnknown *node_object; + WORD node_count; + TOPOID node_id; HRESULT hr; - GUID guid; + BOOL ret;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); ok(hr == S_OK, "Startup failure, hr %#x.\n", hr); @@ -1487,44 +1889,39 @@ 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); + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
- 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 = 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 = IMFMediaSource_CreatePresentationDescriptor(source, &pd); - ok(hr == S_OK, "Failed to create descriptor, hr %#x.\n", hr); - if (FAILED(hr)) - return; + hr = MFCreateStreamDescriptor(0, 1, &media_type, &sd); + ok(hr == S_OK, "Failed to create stream 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 = IMFTopologyNode_SetUnknown(src_node, &MF_TOPONODE_STREAM_DESCRIPTOR, (IUnknown *)sd); + ok(hr == S_OK, "Failed to set node sd, 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); - - 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);
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 +1931,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 +1945,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 +1964,147 @@ 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); + hr = MFCreateMediaType(&input_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
- hr = IMFMediaSink_GetStreamSinkByIndex(sink, 0, &stream_sink); - ok(hr == S_OK, "Unexpected hr %#x.\n", hr); + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Failed to create media type, hr %#x.\n", hr);
- hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)stream_sink); - ok(hr == S_OK, "Failed to set object, hr %#x.\n", hr); + for (i = 0; i < ARRAY_SIZE(loader_tests); ++i) + { + const struct loader_test *test = &loader_tests[i];
- IMFStreamSink_Release(stream_sink); + init_media_type(input_type, test->major, test->input_type.attrs); + init_media_type(output_type, test->major, test->output_type.attrs);
- 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 = MFCreateSampleGrabberSinkActivate(output_type, &test_grabber_callback, &sink_activate); + ok(hr == S_OK, "Failed to create grabber sink, 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"); + init_source_node(input_type, source, src_node); + init_sink_node(sink_activate, test->method, sink_node);
- 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 = IMFTopology_GetCount(topology, &count); + ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr); + ok(!count, "Unexpected count %u.\n", count);
- hr = IMFTopology_GetCount(full_topology, &count); - ok(hr == S_OK, "Failed to get attribute count, hr %#x.\n", hr); + hr = IMFTopoLoader_Load(loader, topology, &full_topology, NULL); +todo_wine_if(test->flags & LOADER_TODO) + ok(hr == test->expected_result, "Unexpected hr %#x on test %u.\n", hr, i); + ok(full_topology != topology, "Unexpected instance.\n"); + + if (test->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); -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)); -} - 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"); + count = 2; + if (test->flags & LOADER_EXPECTED_DECODER) + count++; + if (test->flags & LOADER_EXPECTED_CONVERTER) + count++;
- 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); + todo_wine_if(test->flags & (LOADER_EXPECTED_CONVERTER | LOADER_EXPECTED_DECODER)) + ok(node_count == count, "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 (test->flags & (LOADER_EXPECTED_DECODER | LOADER_EXPECTED_CONVERTER) && strcmp(winetest_platform, "wine")) + { + 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, "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.\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(input_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr); + ok(ret, "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, "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.\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(output_type, (IMFAttributes *)media_type, MF_ATTRIBUTES_MATCH_OUR_ITEMS, &ret); + ok(hr == S_OK, "Failed to compare media types, hr %#x.\n", hr); + ok(ret, "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, "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 diff --git a/dlls/mf/tests/test.wav b/dlls/mf/tests/test.wav deleted file mode 100644 index 51d23936196da1a0452c78713c8af819259d225e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001
literal 4488 zcmWIYbaQJEWMBw)40BD(Em06)U|?VbLYFlRV9dzC!QkT=93ll2_w;k~_Y8Im;RCXL z63fy|&GbwR^b8FQ8B!8U60LxyG&DA~w6?W(c6Imk^!D}jLqT6(Z%=nuXGeQmYjaa$ zeO*m;Rb_cuX-RQWQDFfL6c!d0mz0*3S5#Kl)YdmNHMg|2cYsVnGN`|=7h+OdYfE!u zLtSl6Rb>Ulq(Zn!AcH_ARa910*VfgKI%zbNM$^)0jvFnPMvKbP3T3p~9c`R|TVA8> dC3y36v{gCU_8#q_jCPtvyOyIJ@PQhp007ieqznK6
From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/topology.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 8032e438b73..a09f6ef0ef4 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -2022,8 +2022,6 @@ static HRESULT topology_loader_resolve_branch(struct topoloader_context *context if (FAILED(IMFTopology_GetNodeByID(context->output_topology, id, &node))) topology_loader_clone_node(context, downstream_node, &node, context->marker + 1);
- IMFTopologyNode_ConnectOutput(upstream_node, output_index, node, input_index); - IMFTopologyNode_GetNodeType(upstream_node, &u_type); IMFTopologyNode_GetNodeType(downstream_node, &d_type);
@@ -2033,7 +2031,7 @@ static HRESULT topology_loader_resolve_branch(struct topoloader_context *context return E_FAIL; }
- return connectors[u_type][d_type](context, upstream_node, output_index, downstream_node, input_index); + return connectors[u_type][d_type](context, upstream_node, output_index, node, input_index); }
static HRESULT topology_loader_resolve_nodes(struct topoloader_context *context, unsigned int *layer_size)
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=82732
Your paranoid android.
=== wvistau64 (32 bit report) ===
mf: mf: Timeout
=== wvistau64 (64 bit report) ===
mf: mf: Timeout
From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/topology.c | 273 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 268 insertions(+), 5 deletions(-)
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index a09f6ef0ef4..0ccc8c706b1 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -1992,15 +1992,278 @@ static HRESULT topology_loader_clone_node(struct topoloader_context *context, IM return hr; }
+struct transform_output_type +{ + IMFMediaType *type; + IMFTransform *transform; +}; + +struct connect_context +{ + struct topoloader_context *context; + IMFTopologyNode *upstream_node; + IMFTopologyNode *sink; + IMFMediaTypeHandler *sink_handler; + const GUID *converter_category; +}; + +typedef HRESULT (*p_connect_func)(struct transform_output_type *output_type, struct connect_context *context); + +static void topology_loader_release_transforms(IMFActivate **activates, unsigned int count) +{ + unsigned int i; + + for (i = 0; i < count; ++i) + IMFActivate_Release(activates[i]); + CoTaskMemFree(activates); +} + +static HRESULT topology_loader_enumerate_output_types(const GUID *category, IMFMediaType *input_type, + p_connect_func connect_func, struct connect_context *context) +{ + MFT_REGISTER_TYPE_INFO mft_typeinfo; + IMFActivate **activates; + unsigned int i, count; + HRESULT hr; + + if (FAILED(hr = IMFMediaType_GetMajorType(input_type, &mft_typeinfo.guidMajorType))) + return hr; + + if (FAILED(hr = IMFMediaType_GetGUID(input_type, &MF_MT_SUBTYPE, &mft_typeinfo.guidSubtype))) + return hr; + + if (FAILED(hr = MFTEnumEx(*category, MFT_ENUM_FLAG_ALL, &mft_typeinfo, NULL, &activates, &count))) + return hr; + + hr = E_FAIL; + + for (i = 0; i < count; ++i) + { + IMFTransform *transform; + + if (FAILED(IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void **)&transform))) + { + WARN("Failed to create a transform.\n"); + continue; + } + + if (SUCCEEDED(hr = IMFTransform_SetInputType(transform, 0, input_type, 0))) + { + struct transform_output_type output_type; + unsigned int output_count = 0; + + output_type.transform = transform; + while (SUCCEEDED(IMFTransform_GetOutputAvailableType(transform, 0, output_count++, &output_type.type))) + { + hr = connect_func(&output_type, context); + IMFMediaType_Release(output_type.type); + if (SUCCEEDED(hr)) + { + topology_loader_release_transforms(activates, count); + return hr; + } + } + } + + IMFActivate_ShutdownObject(activates[i]); + } + + topology_loader_release_transforms(activates, count); + + return hr; +} + +static HRESULT connect_to_sink(struct transform_output_type *output_type, struct connect_context *context) +{ + IMFTopologyNode *node; + HRESULT hr; + + if (FAILED(IMFMediaTypeHandler_IsMediaTypeSupported(context->sink_handler, output_type->type, NULL))) + return MF_E_TRANSFORM_NOT_POSSIBLE_FOR_CURRENT_MEDIATYPE_COMBINATION; + + if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node))) + return hr; + + IMFTopologyNode_SetObject(node, (IUnknown *)output_type->transform); + IMFTopology_AddNode(context->context->output_topology, node); + IMFTopologyNode_ConnectOutput(context->upstream_node, 0, node, 0); + IMFTopologyNode_ConnectOutput(node, 0, context->sink, 0); + + IMFTopologyNode_Release(node); + + hr = IMFMediaTypeHandler_SetCurrentMediaType(context->sink_handler, output_type->type); + if (SUCCEEDED(hr)) + hr = IMFTransform_SetOutputType(output_type->transform, 0, output_type->type, 0); + + return S_OK; +} + +static HRESULT connect_to_converter(struct transform_output_type *output_type, struct connect_context *context) +{ + struct connect_context sink_ctx; + IMFTopologyNode *node; + HRESULT hr; + + if (SUCCEEDED(connect_to_sink(output_type, context))) + return S_OK; + + if (FAILED(hr = MFCreateTopologyNode(MF_TOPOLOGY_TRANSFORM_NODE, &node))) + return hr; + + IMFTopologyNode_SetObject(node, (IUnknown *)output_type->transform); + + sink_ctx = *context; + sink_ctx.upstream_node = node; + + if (SUCCEEDED(hr = topology_loader_enumerate_output_types(context->converter_category, output_type->type, + connect_to_sink, &sink_ctx))) + { + hr = IMFTopology_AddNode(context->context->output_topology, node); + } + IMFTopologyNode_Release(node); + + if (SUCCEEDED(hr)) + { + IMFTopology_AddNode(context->context->output_topology, node); + IMFTopologyNode_ConnectOutput(context->upstream_node, 0, node, 0); + + hr = IMFTransform_SetOutputType(output_type->transform, 0, output_type->type, 0); + } + + return hr; +} + typedef HRESULT (*p_topology_loader_connect_func)(struct topoloader_context *context, IMFTopologyNode *upstream_node, unsigned int output_index, IMFTopologyNode *downstream_node, unsigned int input_index);
-static HRESULT topology_loader_connect_source_node(struct topoloader_context *context, IMFTopologyNode *upstream_node, - unsigned int output_index, IMFTopologyNode *downstream_node, unsigned int input_index) +static HRESULT topology_loader_get_node_type_handler(IMFTopologyNode *node, IMFMediaTypeHandler **handler) { - FIXME("Unimplemented.\n"); + MF_TOPOLOGY_TYPE node_type; + IMFStreamSink *stream_sink; + IMFStreamDescriptor *sd; + IUnknown *object; + HRESULT hr;
- return E_NOTIMPL; + if (FAILED(hr = IMFTopologyNode_GetNodeType(node, &node_type))) + return hr; + + switch (node_type) + { + case MF_TOPOLOGY_OUTPUT_NODE: + if (SUCCEEDED(hr = IMFTopologyNode_GetObject(node, (IUnknown **)&object))) + { + if (SUCCEEDED(hr = IUnknown_QueryInterface(object, &IID_IMFStreamSink, (void **)&stream_sink))) + { + hr = IMFStreamSink_GetMediaTypeHandler(stream_sink, handler); + IMFStreamSink_Release(stream_sink); + } + IUnknown_Release(object); + } + break; + case MF_TOPOLOGY_SOURCESTREAM_NODE: + if (SUCCEEDED(hr = IMFTopologyNode_GetUnknown(node, &MF_TOPONODE_STREAM_DESCRIPTOR, + &IID_IMFStreamDescriptor, (void **)&sd))) + { + hr = IMFStreamDescriptor_GetMediaTypeHandler(sd, handler); + IMFStreamDescriptor_Release(sd); + } + break; + default: + WARN("Unexpected node type %u.\n", node_type); + return MF_E_UNEXPECTED; + } + + return hr; +} + +static HRESULT topology_loader_get_mft_categories(IMFMediaTypeHandler *handler, GUID *decode_cat, GUID *convert_cat) +{ + GUID major; + HRESULT hr; + + if (FAILED(hr = IMFMediaTypeHandler_GetMajorType(handler, &major))) + return hr; + + if (IsEqualGUID(&major, &MFMediaType_Audio)) + { + *decode_cat = MFT_CATEGORY_AUDIO_DECODER; + *convert_cat = MFT_CATEGORY_AUDIO_EFFECT; + } + else if (IsEqualGUID(&major, &MFMediaType_Video)) + { + *decode_cat = MFT_CATEGORY_VIDEO_DECODER; + *convert_cat = MFT_CATEGORY_VIDEO_EFFECT; + } + else + { + WARN("Unexpected major type %s.\n", debugstr_guid(&major)); + return MF_E_INVALIDTYPE; + } + + return S_OK; +} + +static HRESULT topology_loader_connect_source_to_sink(struct topoloader_context *context, IMFTopologyNode *source, + unsigned int output_index, IMFTopologyNode *sink, unsigned int input_index) +{ + IMFMediaTypeHandler *source_handler = NULL, *sink_handler = NULL; + struct connect_context convert_ctx, sink_ctx; + MF_CONNECT_METHOD source_method, sink_method; + GUID decode_cat, convert_cat; + IMFMediaType *media_type; + HRESULT hr; + + TRACE("attempting to connect %p:%u to %p:%u\n", source, output_index, sink, input_index); + + if (FAILED(hr = topology_loader_get_node_type_handler(source, &source_handler))) + goto done; + + if (FAILED(hr = topology_loader_get_node_type_handler(sink, &sink_handler))) + goto done; + + if (FAILED(IMFTopologyNode_GetUINT32(source, &MF_TOPONODE_CONNECT_METHOD, &source_method))) + source_method = MF_CONNECT_DIRECT; + if (FAILED(IMFTopologyNode_GetUINT32(sink, &MF_TOPONODE_CONNECT_METHOD, &sink_method))) + sink_method = MF_CONNECT_ALLOW_DECODER; + + if (FAILED(hr = topology_loader_get_mft_categories(source_handler, &decode_cat, &convert_cat))) + goto done; + + sink_ctx.context = context; + sink_ctx.upstream_node = source; + sink_ctx.sink = sink; + sink_ctx.sink_handler = sink_handler; + + convert_ctx = sink_ctx; + convert_ctx.converter_category = &convert_cat; + + if (SUCCEEDED(hr = IMFMediaTypeHandler_GetCurrentMediaType(source_handler, &media_type))) + { + /* Direct connection. */ + if (SUCCEEDED(hr = IMFMediaTypeHandler_IsMediaTypeSupported(sink_handler, media_type, NULL)) + && SUCCEEDED(hr = IMFMediaTypeHandler_SetCurrentMediaType(sink_handler, media_type))) + { + hr = IMFTopologyNode_ConnectOutput(source, output_index, sink, input_index); + } + else if (sink_method & MF_CONNECT_ALLOW_CONVERTER) + { + hr = topology_loader_enumerate_output_types(&convert_cat, media_type, connect_to_sink, &sink_ctx); + } + else if (sink_method & MF_CONNECT_ALLOW_DECODER) + { + hr = topology_loader_enumerate_output_types(&decode_cat, media_type, connect_to_converter, &convert_ctx); + } + + IMFMediaType_Release(media_type); + } + +done: + if (source_handler) + IMFMediaTypeHandler_Release(source_handler); + if (sink_handler) + IMFMediaTypeHandler_Release(sink_handler); + + return hr; }
static HRESULT topology_loader_resolve_branch(struct topoloader_context *context, IMFTopologyNode *upstream_node, @@ -2009,7 +2272,7 @@ static HRESULT topology_loader_resolve_branch(struct topoloader_context *context static const p_topology_loader_connect_func connectors[MF_TOPOLOGY_TEE_NODE+1][MF_TOPOLOGY_TEE_NODE+1] = { /* OUTPUT */ { NULL }, - /* SOURCESTREAM */ { topology_loader_connect_source_node, NULL, NULL, NULL }, + /* SOURCESTREAM */ { topology_loader_connect_source_to_sink, NULL, NULL, NULL }, /* TRANSFORM */ { NULL }, /* TEE */ { NULL }, };
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=82733
Your paranoid android.
=== wvistau64 (32 bit report) ===
mf: mf: Timeout
=== wvistau64 (64 bit report) ===
mf: mf: Timeout
From: Derek Lesho dlesho@codeweavers.com
Signed-off-by: Derek Lesho dlesho@codeweavers.com Signed-off-by: Nikolay Sivov nsivov@codeweavers.com --- dlls/mf/tests/mf.c | 6 ++---- dlls/mf/topology.c | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 5e5c30ec6fc..20e3e8713c6 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1735,7 +1735,6 @@ static void test_topology_loader(void)
MF_CONNECT_DIRECT, MF_E_INVALIDMEDIATYPE, - LOADER_TODO, },
{ @@ -1766,7 +1765,7 @@ static void test_topology_loader(void)
MF_CONNECT_ALLOW_CONVERTER, S_OK, - LOADER_EXPECTED_CONVERTER, + LOADER_EXPECTED_CONVERTER | LOADER_TODO, },
{ @@ -1794,7 +1793,6 @@ static void test_topology_loader(void)
MF_CONNECT_DIRECT, MF_E_INVALIDMEDIATYPE, - LOADER_TODO, },
{ @@ -1850,7 +1848,7 @@ static void test_topology_loader(void)
MF_CONNECT_ALLOW_DECODER, S_OK, - LOADER_EXPECTED_DECODER, + LOADER_EXPECTED_DECODER | LOADER_TODO, }, };
diff --git a/dlls/mf/topology.c b/dlls/mf/topology.c index 0ccc8c706b1..0b1b095729b 100644 --- a/dlls/mf/topology.c +++ b/dlls/mf/topology.c @@ -2429,11 +2429,9 @@ static HRESULT WINAPI topology_loader_Load(IMFTopoLoader *iface, IMFTopology *in break; }
- /* For now return original topology. */ - *ret_topology = output_topology;
- return IMFTopology_CloneFrom(output_topology, input_topology); + return hr; }
static const IMFTopoLoaderVtbl topologyloadervtbl =
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=82734
Your paranoid android.
=== wvistau64 (32 bit report) ===
mf: mf: Timeout
=== wvistau64 (64 bit report) ===
mf: mf: Timeout
Hi,
While running your changed tests, I think I found new failures. Being a bot and all I'm not very good at pattern recognition, so I might be wrong, but could you please double-check?
Full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=82731
Your paranoid android.
=== wvistau64 (32 bit report) ===
mf: mf: Timeout
=== wvistau64 (64 bit report) ===
mf: mf: Timeout