First change also avoids a leak of classes (later activates) when the transform is successfully connected.
The use of MFTEnumEx is necessary so that the tests work, as they use a locally registered transform.
-- v2: mfreadwrite/tests: Test the D3D awareness of source reader transforms. mfreadwrite/tests: Test the source reader stream change events. mfreadwrite/reader: Make the GetTransformForStream category parameter optional. mfreadwrite/reader: Use MFTEnumEx to enumerate stream transforms.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/reader.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index b77b5f9c538..2baa3810ee0 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1926,7 +1926,8 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL { MFT_REGISTER_TYPE_INFO in_type, out_type; struct transform_entry *entry; - GUID *classes, category; + IMFActivate **activates; + GUID category; IMFTransform *transform; UINT i, count; HRESULT hr; @@ -1960,7 +1961,7 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL }
count = 0; - if (SUCCEEDED(hr = MFTEnum(category, 0, &in_type, allow_processor ? NULL : &out_type, NULL, &classes, &count))) + if (SUCCEEDED(hr = MFTEnumEx(category, 0, &in_type, allow_processor ? NULL : &out_type, &activates, &count))) { if (!count) { @@ -1972,8 +1973,8 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL { IMFMediaType *media_type;
- if (FAILED(hr = CoCreateInstance(&classes[i], NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform))) - break; + if (FAILED(IMFActivate_ActivateObject(activates[i], &IID_IMFTransform, (void **)&transform))) + continue; if (SUCCEEDED(hr = IMFTransform_SetInputType(transform, 0, input_type, 0)) && SUCCEEDED(hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type))) { @@ -1995,17 +1996,20 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL { entry->transform = transform; *out = entry; - return S_OK; + break; } }
IMFTransform_Release(transform); }
- CoTaskMemFree(classes); + for (i = 0; i < count; ++i) + IMFActivate_Release(activates[i]); + CoTaskMemFree(activates); }
- free(entry); + if (FAILED(hr)) + free(entry); return hr; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/reader.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 2baa3810ee0..252e0c1f51c 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -2512,6 +2512,9 @@ static HRESULT WINAPI src_reader_GetTransformForStream(IMFSourceReaderEx *iface,
TRACE("%p, %#lx, %#lx, %p, %p.\n", iface, stream_index, transform_index, category, transform);
+ if (!transform) + return E_POINTER; + EnterCriticalSection(&reader->cs);
if (stream_index == MF_SOURCE_READER_FIRST_VIDEO_STREAM) @@ -2525,7 +2528,8 @@ static HRESULT WINAPI src_reader_GetTransformForStream(IMFSourceReaderEx *iface, hr = MF_E_INVALIDINDEX; else { - *category = entry->category; + if (category) + *category = entry->category; *transform = entry->transform; IMFTransform_AddRef(*transform); hr = S_OK;
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/tests/mfplat.c | 524 ++++++++++++++++++++++++++++++++ 1 file changed, 524 insertions(+)
diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index aacd3c101b8..9cf93c72eb8 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -39,11 +39,14 @@ DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); #include "mferror.h" #include "mfreadwrite.h" #include "propvarutil.h" +#include "initguid.h" #include "d3d9.h" #include "dxva2api.h"
#include "wine/test.h"
+DEFINE_MEDIATYPE_GUID(MFVideoFormat_TEST,MAKEFOURCC('T','E','S','T')); + struct attribute_desc { const GUID *key; @@ -2255,6 +2258,526 @@ skip_tests: winetest_pop_context(); }
+struct test_decoder +{ + IMFTransform IMFTransform_iface; + LONG refcount; + + IMFMediaType *input_type; + IMFMediaType *output_type; + + MFVIDEOFORMAT output_format; + HRESULT next_output; +}; + +static struct test_decoder *test_decoder_from_IMFTransform(IMFTransform *iface) +{ + return CONTAINING_RECORD(iface, struct test_decoder, IMFTransform_iface); +} + +static HRESULT WINAPI test_decoder_QueryInterface(IMFTransform *iface, REFIID iid, void **out) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + + if (IsEqualGUID(iid, &IID_IUnknown) || + IsEqualGUID(iid, &IID_IMFTransform)) + { + IMFTransform_AddRef(&decoder->IMFTransform_iface); + *out = &decoder->IMFTransform_iface; + return S_OK; + } + + *out = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_decoder_AddRef(IMFTransform *iface) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + ULONG refcount = InterlockedIncrement(&decoder->refcount); + return refcount; +} + +static ULONG WINAPI test_decoder_Release(IMFTransform *iface) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + ULONG refcount = InterlockedDecrement(&decoder->refcount); + + if (!refcount) + { + if (decoder->input_type) + IMFMediaType_Release(decoder->input_type); + if (decoder->output_type) + IMFMediaType_Release(decoder->output_type); + free(decoder); + } + + return refcount; +} + +static HRESULT WINAPI test_decoder_GetStreamLimits(IMFTransform *iface, DWORD *input_minimum, + DWORD *input_maximum, DWORD *output_minimum, DWORD *output_maximum) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetStreamCount(IMFTransform *iface, DWORD *inputs, DWORD *outputs) +{ + *inputs = *outputs = 1; + return S_OK; +} + +static HRESULT WINAPI test_decoder_GetStreamIDs(IMFTransform *iface, DWORD input_size, DWORD *inputs, + DWORD output_size, DWORD *outputs) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetInputStreamInfo(IMFTransform *iface, DWORD id, MFT_INPUT_STREAM_INFO *info) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetOutputStreamInfo(IMFTransform *iface, DWORD id, MFT_OUTPUT_STREAM_INFO *info) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + UINT64 frame_size; + GUID subtype; + + if (!decoder->output_type || FAILED(IMFMediaType_GetUINT64(decoder->output_type, &MF_MT_FRAME_SIZE, &frame_size))) + frame_size = (UINT64)96 << 32 | 96; + if (!decoder->output_type || FAILED(IMFMediaType_GetGUID(decoder->output_type, &MF_MT_SUBTYPE, &subtype))) + subtype = MFVideoFormat_YUY2; + + memset(info, 0, sizeof(*info)); + return MFCalculateImageSize(&MFVideoFormat_RGB32, (UINT32)frame_size, frame_size >> 32, (UINT32 *)&info->cbSize); +} + +static HRESULT WINAPI test_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetOutputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) +{ + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_DeleteInputStream(IMFTransform *iface, DWORD id) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_AddInputStreams(IMFTransform *iface, DWORD streams, DWORD *ids) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetInputAvailableType(IMFTransform *iface, DWORD id, DWORD index, + IMFMediaType **type) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static void test_decoder_set_output_format(IMFTransform *iface, const MFVIDEOFORMAT *output_format) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + decoder->output_format = *output_format; +} + +static HRESULT WINAPI test_decoder_GetOutputAvailableType(IMFTransform *iface, DWORD id, + DWORD index, IMFMediaType **type) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + const GUID subtypes[] = + { + MFVideoFormat_NV12, + MFVideoFormat_YUY2, + }; + MFVIDEOFORMAT format = + { + .dwSize = sizeof(format), + .videoInfo = + { + .dwWidth = 96, + .dwHeight = 96, + }, + }; + HRESULT hr; + + *type = NULL; + if (index >= ARRAY_SIZE(subtypes)) + return MF_E_NO_MORE_TYPES; + + if (decoder->output_format.dwSize) + format = decoder->output_format; + format.guidFormat = subtypes[index]; + + hr = MFCreateMediaType(type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFInitMediaTypeFromMFVideoFormat(*type, &format, sizeof(format)); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + return hr; +} + +static HRESULT WINAPI test_decoder_SetInputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + if (flags & MFT_SET_TYPE_TEST_ONLY) + return S_OK; + if (decoder->input_type) + IMFMediaType_Release(decoder->input_type); + if ((decoder->input_type = type)) + IMFMediaType_AddRef(decoder->input_type); + return S_OK; +} + +static HRESULT WINAPI test_decoder_SetOutputType(IMFTransform *iface, DWORD id, IMFMediaType *type, DWORD flags) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + if (flags & MFT_SET_TYPE_TEST_ONLY) + return S_OK; + if (decoder->output_type) + IMFMediaType_Release(decoder->output_type); + if ((decoder->output_type = type)) + IMFMediaType_AddRef(decoder->output_type); + return S_OK; +} + +static HRESULT WINAPI test_decoder_GetInputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + if (!(*type = decoder->input_type)) + return MF_E_TRANSFORM_TYPE_NOT_SET; + IMFMediaType_AddRef(*type); + return S_OK; +} + +static HRESULT WINAPI test_decoder_GetOutputCurrentType(IMFTransform *iface, DWORD id, IMFMediaType **type) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + if (!(*type = decoder->output_type)) + return MF_E_TRANSFORM_TYPE_NOT_SET; + IMFMediaType_AddRef(*type); + return S_OK; +} + +static HRESULT WINAPI test_decoder_GetInputStatus(IMFTransform *iface, DWORD id, DWORD *flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_GetOutputStatus(IMFTransform *iface, DWORD *flags) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_SetOutputBounds(IMFTransform *iface, LONGLONG lower, LONGLONG upper) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_ProcessEvent(IMFTransform *iface, DWORD id, IMFMediaEvent *event) +{ + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; +} + +static HRESULT WINAPI test_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSAGE_TYPE message, ULONG_PTR param) +{ + switch (message) + { + case MFT_MESSAGE_COMMAND_FLUSH: + case MFT_MESSAGE_NOTIFY_BEGIN_STREAMING: + case MFT_MESSAGE_NOTIFY_END_STREAMING: + case MFT_MESSAGE_NOTIFY_END_OF_STREAM: + case MFT_MESSAGE_NOTIFY_START_OF_STREAM: + return S_OK; + + default: + ok(0, "Unexpected call.\n"); + return E_NOTIMPL; + } +} + +static HRESULT WINAPI test_decoder_ProcessInput(IMFTransform *iface, DWORD id, IMFSample *sample, DWORD flags) +{ + return S_OK; +} + +static void test_decoder_set_next_output(IMFTransform *iface, HRESULT hr) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + decoder->next_output = hr; +} + +static HRESULT WINAPI test_decoder_ProcessOutput(IMFTransform *iface, DWORD flags, DWORD count, + MFT_OUTPUT_DATA_BUFFER *data, DWORD *status) +{ + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + + if (decoder->next_output == MF_E_TRANSFORM_STREAM_CHANGE) + { + data[0].dwStatus = MFT_OUTPUT_DATA_BUFFER_FORMAT_CHANGE; + decoder->next_output = S_OK; + return MF_E_TRANSFORM_STREAM_CHANGE; + } + + if (decoder->next_output == S_OK) + { + decoder->next_output = MF_E_TRANSFORM_NEED_MORE_INPUT; + return S_OK; + } + + return decoder->next_output; +} + +static const IMFTransformVtbl test_decoder_vtbl = +{ + test_decoder_QueryInterface, + test_decoder_AddRef, + test_decoder_Release, + test_decoder_GetStreamLimits, + test_decoder_GetStreamCount, + test_decoder_GetStreamIDs, + test_decoder_GetInputStreamInfo, + test_decoder_GetOutputStreamInfo, + test_decoder_GetAttributes, + test_decoder_GetInputStreamAttributes, + test_decoder_GetOutputStreamAttributes, + test_decoder_DeleteInputStream, + test_decoder_AddInputStreams, + test_decoder_GetInputAvailableType, + test_decoder_GetOutputAvailableType, + test_decoder_SetInputType, + test_decoder_SetOutputType, + test_decoder_GetInputCurrentType, + test_decoder_GetOutputCurrentType, + test_decoder_GetInputStatus, + test_decoder_GetOutputStatus, + test_decoder_SetOutputBounds, + test_decoder_ProcessEvent, + test_decoder_ProcessMessage, + test_decoder_ProcessInput, + test_decoder_ProcessOutput, +}; + +static HRESULT WINAPI test_mft_factory_QueryInterface(IClassFactory *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IClassFactory) || + IsEqualIID(riid, &IID_IUnknown)) + { + *obj = iface; + IClassFactory_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_mft_factory_AddRef(IClassFactory *iface) +{ + return 2; +} + +static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface) +{ + return 1; +} + +static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj) +{ + struct test_decoder *decoder; + + if (!(decoder = calloc(1, sizeof(*decoder)))) + return E_OUTOFMEMORY; + decoder->IMFTransform_iface.lpVtbl = &test_decoder_vtbl; + decoder->refcount = 1; + + *obj = &decoder->IMFTransform_iface; + return S_OK; +} + +static HRESULT WINAPI test_mft_factory_LockServer(IClassFactory *iface, BOOL fLock) +{ + return S_OK; +} + +static const IClassFactoryVtbl test_mft_factory_vtbl = +{ + test_mft_factory_QueryInterface, + test_mft_factory_AddRef, + test_mft_factory_Release, + test_mft_factory_CreateInstance, + test_mft_factory_LockServer, +}; + +static void test_source_reader_transform_stream_change(void) +{ + static const struct attribute_desc test_stream_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_TEST), + ATTR_RATIO(MF_MT_FRAME_SIZE, 96, 96), + {0}, + }; + static const struct attribute_desc yuy2_stream_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), + {0}, + }; + static const struct attribute_desc yuy2_expect_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2), + ATTR_RATIO(MF_MT_FRAME_SIZE, 96, 96), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1, .todo = TRUE), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1, .todo = TRUE), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 96 * 2, .todo = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 96 * 96 * 2, .todo = TRUE), + {0}, + }; + static const struct attribute_desc yuy2_expect_new_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_YUY2, .todo_value = TRUE), + ATTR_RATIO(MF_MT_FRAME_SIZE, 128, 128), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1), + ATTR_UINT32(MF_MT_FIXED_SIZE_SAMPLES, 1), + ATTR_UINT32(MF_MT_DEFAULT_STRIDE, 128 * 2, .todo_value = TRUE), + ATTR_UINT32(MF_MT_SAMPLE_SIZE, 128 * 128 * 2, .todo_value = TRUE), + {0}, + }; + const MFT_REGISTER_TYPE_INFO output_info[] = + { + {MFMediaType_Video, MFVideoFormat_NV12}, + {MFMediaType_Video, MFVideoFormat_YUY2}, + }; + const MFT_REGISTER_TYPE_INFO input_info[] = + { + {MFMediaType_Video, MFVideoFormat_TEST}, + }; + MFVIDEOFORMAT output_format = {.dwSize = sizeof(output_format)}; + IClassFactory factory = {.lpVtbl = &test_mft_factory_vtbl}; + IMFStreamDescriptor *video_stream; + IMFSourceReaderEx *reader_ex; + IMFTransform *test_decoder; + IMFMediaType *media_type; + IMFSourceReader *reader; + IMFMediaSource *source; + LONGLONG timestamp; + DWORD index, flags; + IMFSample *sample; + GUID category; + HRESULT hr; + + + hr = MFTRegisterLocal(&factory, &MFT_CATEGORY_VIDEO_DECODER, L"Test Decoder", 0, + ARRAY_SIZE(input_info), input_info, ARRAY_SIZE(output_info), output_info); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* test source reader with a custom source */ + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, test_stream_type_desc, -1); + hr = MFCreateStreamDescriptor(0, 1, &media_type, &video_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + source = create_test_source(&video_stream, 1); + ok(!!source, "Failed to create test source.\n"); + IMFStreamDescriptor_Release(video_stream); + + hr = MFCreateSourceReaderFromMediaSource(source, NULL, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaSource_Release(source); + + hr = IMFSourceReader_SetStreamSelection(reader, 0, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + + hr = IMFSourceReader_GetNativeMediaType(reader, 0, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, test_stream_type_desc, -1); + IMFMediaType_Release(media_type); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, test_stream_type_desc, -1); + IMFMediaType_Release(media_type); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, yuy2_stream_type_desc, -1); + hr = IMFSourceReader_SetCurrentMediaType(reader, 0, NULL, media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, yuy2_expect_desc, -1); + IMFMediaType_Release(media_type); + + + + hr = IMFSourceReader_QueryInterface(reader, &IID_IMFSourceReaderEx, (void **)&reader_ex); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFSourceReaderEx_GetTransformForStream(reader_ex, 0, 0, &category, NULL); + ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr); + hr = IMFSourceReaderEx_GetTransformForStream(reader_ex, 0, 0, NULL, &test_decoder); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(test_decoder->lpVtbl == &test_decoder_vtbl, "got unexpected transform\n"); + IMFSourceReaderEx_Release(reader_ex); + + fail_request_sample = FALSE; + + test_decoder_set_next_output(test_decoder, MF_E_TRANSFORM_STREAM_CHANGE); + + output_format.videoInfo.dwHeight = 128; + output_format.videoInfo.dwWidth = 128; + test_decoder_set_output_format(test_decoder, &output_format); + + sample = (void *)0xdeadbeef; + index = flags = timestamp = 0xdeadbeef; + hr = IMFSourceReader_ReadSample(reader, 0, 0, &index, &flags, ×tamp, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(index == 0, "got %lu.\n", index); + ok(flags == MF_SOURCE_READERF_CURRENTMEDIATYPECHANGED, "got %lu.\n", flags); + ok(timestamp == 0, "got %I64d.\n", timestamp); + ok(sample != (void *)0xdeadbeef, "got %p.\n", sample); + IMFSample_Release(sample); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, yuy2_expect_new_desc, -1); + IMFMediaType_Release(media_type); + + fail_request_sample = TRUE; + + IMFTransform_Release(test_decoder); + + IMFSourceReader_Release(reader); + + hr = MFTUnregisterLocal(&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); +} + START_TEST(mfplat) { HRESULT hr; @@ -2272,6 +2795,7 @@ START_TEST(mfplat) test_source_reader_transforms(FALSE, FALSE); test_source_reader_transforms(TRUE, FALSE); test_source_reader_transforms(FALSE, TRUE); + test_source_reader_transform_stream_change(); test_reader_d3d9(); test_sink_writer_create(); test_sink_writer_mp4();
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/tests/Makefile.in | 2 +- dlls/mfreadwrite/tests/mfplat.c | 387 ++++++++++++++++++++++++++++- 2 files changed, 387 insertions(+), 2 deletions(-)
diff --git a/dlls/mfreadwrite/tests/Makefile.in b/dlls/mfreadwrite/tests/Makefile.in index cada1bf22ff..3bdab217148 100644 --- a/dlls/mfreadwrite/tests/Makefile.in +++ b/dlls/mfreadwrite/tests/Makefile.in @@ -1,5 +1,5 @@ TESTDLL = mfreadwrite.dll -IMPORTS = ole32 user32 d3d9 dxva2 mfplat mfreadwrite mfuuid propsys +IMPORTS = ole32 user32 d3d9 dxva2 mfplat mf mfreadwrite mfuuid propsys
SOURCES = \ mfplat.c \ diff --git a/dlls/mfreadwrite/tests/mfplat.c b/dlls/mfreadwrite/tests/mfplat.c index 9cf93c72eb8..ef0e622dab2 100644 --- a/dlls/mfreadwrite/tests/mfplat.c +++ b/dlls/mfreadwrite/tests/mfplat.c @@ -42,11 +42,42 @@ DEFINE_GUID(GUID_NULL, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); #include "initguid.h" #include "d3d9.h" #include "dxva2api.h" +#include "evr.h"
#include "wine/test.h"
DEFINE_MEDIATYPE_GUID(MFVideoFormat_TEST,MAKEFOURCC('T','E','S','T'));
+#define check_interface(a, b, c) check_interface_(__LINE__, a, b, c) +static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = IUnknown_QueryInterface(iface, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + +#define check_service_interface(a, b, c, d) check_service_interface_(__LINE__, a, b, c, d) +static void check_service_interface_(unsigned int line, void *iface_ptr, REFGUID service, REFIID iid, BOOL supported) +{ + IUnknown *iface = iface_ptr; + HRESULT hr, expected_hr; + IUnknown *unk; + + expected_hr = supported ? S_OK : E_NOINTERFACE; + + hr = MFGetService(iface, service, iid, (void **)&unk); + ok_(__FILE__, line)(hr == expected_hr, "Got hr %#lx, expected %#lx.\n", hr, expected_hr); + if (SUCCEEDED(hr)) + IUnknown_Release(unk); +} + struct attribute_desc { const GUID *key; @@ -2258,11 +2289,17 @@ skip_tests: winetest_pop_context(); }
+static BOOL test_decoder_d3d_aware; +static BOOL test_decoder_got_d3d_manager; +static BOOL test_decoder_allocate_samples; +static IDirect3DDeviceManager9 *expect_d3d_manager; + struct test_decoder { IMFTransform IMFTransform_iface; LONG refcount;
+ IMFAttributes *attributes; IMFMediaType *input_type; IMFMediaType *output_type;
@@ -2352,12 +2389,18 @@ static HRESULT WINAPI test_decoder_GetOutputStreamInfo(IMFTransform *iface, DWOR subtype = MFVideoFormat_YUY2;
memset(info, 0, sizeof(*info)); + if (test_decoder_allocate_samples) + info->dwFlags |= MFT_OUTPUT_STREAM_PROVIDES_SAMPLES; return MFCalculateImageSize(&MFVideoFormat_RGB32, (UINT32)frame_size, frame_size >> 32, (UINT32 *)&info->cbSize); }
static HRESULT WINAPI test_decoder_GetAttributes(IMFTransform *iface, IMFAttributes **attributes) { - return E_NOTIMPL; + struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + if (!(*attributes = decoder->attributes)) + return E_NOTIMPL; + IMFAttributes_AddRef(*attributes); + return S_OK; }
static HRESULT WINAPI test_decoder_GetInputStreamAttributes(IMFTransform *iface, DWORD id, IMFAttributes **attributes) @@ -2507,6 +2550,22 @@ static HRESULT WINAPI test_decoder_ProcessMessage(IMFTransform *iface, MFT_MESSA case MFT_MESSAGE_NOTIFY_START_OF_STREAM: return S_OK;
+ case MFT_MESSAGE_SET_D3D_MANAGER: + ok(test_decoder_d3d_aware, "Unexpected call.\n"); + if (param) + { + IDirect3DDeviceManager9 *manager; + HRESULT hr; + + hr = IUnknown_QueryInterface((IUnknown *)param, &IID_IDirect3DDeviceManager9, (void **)&manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(manager == expect_d3d_manager, "got manager %p\n", manager); + IDirect3DDeviceManager9_Release(manager); + + test_decoder_got_d3d_manager = TRUE; + } + return test_decoder_d3d_aware ? S_OK : E_NOTIMPL; + default: ok(0, "Unexpected call.\n"); return E_NOTIMPL; @@ -2528,6 +2587,38 @@ static HRESULT WINAPI test_decoder_ProcessOutput(IMFTransform *iface, DWORD flag MFT_OUTPUT_DATA_BUFFER *data, DWORD *status) { struct test_decoder *decoder = test_decoder_from_IMFTransform(iface); + IMFMediaBuffer *buffer; + IUnknown *unknown; + HRESULT hr; + + if (test_decoder_allocate_samples) + { + ok(!data->pSample, "Unexpected sample\n"); + + hr = MFCreateSample(&data->pSample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateMediaBufferFromMediaType(decoder->output_type, 0, 0, 0, &buffer); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + if (hr != S_OK) + { + hr = MFCreateMemoryBuffer(96 * 96 * 4, &buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + hr = IMFSample_AddBuffer(data->pSample, buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaBuffer_Release(buffer); + } + + ok(!!data->pSample, "Missing sample\n"); + + hr = IMFSample_GetBufferByIndex(data->pSample, 0, &buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + todo_wine check_interface(buffer, &IID_IMF2DBuffer2, TRUE); + todo_wine check_interface(buffer, &IID_IMFGetService, TRUE); + check_interface(buffer, &IID_IMFDXGIBuffer, FALSE); + hr = MFGetService((IUnknown *)buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, (void **)&unknown); + todo_wine ok(hr == E_NOTIMPL, "Unexpected hr %#lx.\n", hr); + IMFMediaBuffer_Release(buffer);
if (decoder->next_output == MF_E_TRANSFORM_STREAM_CHANGE) { @@ -2539,6 +2630,8 @@ static HRESULT WINAPI test_decoder_ProcessOutput(IMFTransform *iface, DWORD flag if (decoder->next_output == S_OK) { decoder->next_output = MF_E_TRANSFORM_NEED_MORE_INPUT; + hr = IMFSample_SetSampleTime(data->pSample, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); return S_OK; }
@@ -2602,12 +2695,21 @@ static ULONG WINAPI test_mft_factory_Release(IClassFactory *iface) static HRESULT WINAPI test_mft_factory_CreateInstance(IClassFactory *iface, IUnknown *outer, REFIID riid, void **obj) { struct test_decoder *decoder; + HRESULT hr;
if (!(decoder = calloc(1, sizeof(*decoder)))) return E_OUTOFMEMORY; decoder->IMFTransform_iface.lpVtbl = &test_decoder_vtbl; decoder->refcount = 1;
+ if (test_decoder_d3d_aware) + { + hr = MFCreateAttributes(&decoder->attributes, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUINT32(decoder->attributes, &MF_SA_D3D_AWARE, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + *obj = &decoder->IMFTransform_iface; return S_OK; } @@ -2778,6 +2880,288 @@ static void test_source_reader_transform_stream_change(void) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
+static void test_source_reader_transforms_d3d(void) +{ + static const struct attribute_desc test_stream_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_TEST), + ATTR_RATIO(MF_MT_FRAME_SIZE, 96, 96), + {0}, + }; + static const struct attribute_desc rgb32_stream_type_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + {0}, + }; + static const struct attribute_desc rgb32_expect_desc[] = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, MFVideoFormat_RGB32), + ATTR_RATIO(MF_MT_FRAME_SIZE, 96, 96), + ATTR_UINT32(MF_MT_ALL_SAMPLES_INDEPENDENT, 1, .todo = TRUE), + ATTR_UINT32(MF_MT_COMPRESSED, 0, .todo = TRUE), + ATTR_UINT32(MF_MT_INTERLACE_MODE, 2, .todo = TRUE), + {0}, + }; + const MFT_REGISTER_TYPE_INFO output_info[] = + { + {MFMediaType_Video, MFVideoFormat_NV12}, + {MFMediaType_Video, MFVideoFormat_YUY2}, + }; + const MFT_REGISTER_TYPE_INFO input_info[] = + { + {MFMediaType_Video, MFVideoFormat_TEST}, + }; + IClassFactory factory = {.lpVtbl = &test_mft_factory_vtbl}; + IMFTransform *test_decoder, *video_processor; + IDirect3DDeviceManager9 *d3d9_manager; + IMFStreamDescriptor *video_stream; + IDirect3DDevice9 *d3d9_device; + IMFSourceReaderEx *reader_ex; + IMFAttributes *attributes; + IMFMediaType *media_type; + IMFSourceReader *reader; + IMFMediaBuffer *buffer; + IMFMediaSource *source; + LONGLONG timestamp; + DWORD index, flags; + IMFSample *sample; + IDirect3D9 *d3d9; + UINT32 value; + HWND window; + UINT token; + HRESULT hr; + + d3d9 = Direct3DCreate9(D3D_SDK_VERSION); + if (!d3d9) + { + skip("Failed to create a D3D9 object, skipping tests.\n"); + return; + } + + window = create_window(); + if (!(d3d9_device = create_d3d9_device(d3d9, window))) + { + skip("Failed to create a D3D9 device, skipping tests.\n"); + goto done; + } + + test_decoder_d3d_aware = TRUE; + + hr = MFTRegisterLocal(&factory, &MFT_CATEGORY_VIDEO_DECODER, L"Test Decoder", 0, + ARRAY_SIZE(input_info), input_info, ARRAY_SIZE(output_info), output_info); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateAttributes(&attributes, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUINT32(attributes, &MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = DXVA2CreateDirect3DDeviceManager9(&token, &d3d9_manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IDirect3DDeviceManager9_ResetDevice(d3d9_manager, d3d9_device, token); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUnknown(attributes, &MF_SOURCE_READER_D3D_MANAGER, (IUnknown *)d3d9_manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + expect_d3d_manager = d3d9_manager; + + + /* test d3d aware decoder that doesn't allocate buffers */ + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, test_stream_type_desc, -1); + hr = MFCreateStreamDescriptor(0, 1, &media_type, &video_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + source = create_test_source(&video_stream, 1); + ok(!!source, "Failed to create test source.\n"); + IMFStreamDescriptor_Release(video_stream); + + hr = MFCreateSourceReaderFromMediaSource(source, attributes, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFAttributes_Release(attributes); + IMFMediaSource_Release(source); + + hr = IMFSourceReader_SetStreamSelection(reader, 0, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFSourceReader_GetNativeMediaType(reader, 0, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, test_stream_type_desc, -1); + IMFMediaType_Release(media_type); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, test_stream_type_desc, -1); + IMFMediaType_Release(media_type); + ok(!test_decoder_got_d3d_manager, "d3d manager received\n"); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, rgb32_stream_type_desc, -1); + hr = IMFSourceReader_SetCurrentMediaType(reader, 0, NULL, media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + todo_wine ok(!!test_decoder_got_d3d_manager, "d3d manager not received\n"); + + hr = IMFSourceReader_GetCurrentMediaType(reader, 0, &media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_media_type(media_type, rgb32_expect_desc, -1); + IMFMediaType_Release(media_type); + + + hr = IMFSourceReader_QueryInterface(reader, &IID_IMFSourceReaderEx, (void **)&reader_ex); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + /* video processor transform is not D3D aware */ + hr = IMFSourceReaderEx_GetTransformForStream(reader_ex, 0, 1, NULL, &video_processor); + todo_wine ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + /* FIXME: Wine skips the video processor as the test decoder accepts the output type directly */ + if (hr == S_OK) + { + ok(video_processor->lpVtbl != &test_decoder_vtbl, "got unexpected transform\n"); + hr = IMFTransform_GetAttributes(video_processor, &attributes); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_GetUINT32(attributes, &MF_SA_D3D_AWARE, &value); + ok(hr == MF_E_ATTRIBUTENOTFOUND, "Unexpected hr %#lx.\n", hr); + IMFAttributes_Release(attributes); + IMFTransform_Release(video_processor); + } + + hr = IMFSourceReaderEx_GetTransformForStream(reader_ex, 0, 0, NULL, &test_decoder); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(test_decoder->lpVtbl == &test_decoder_vtbl, "got unexpected transform\n"); + hr = IMFTransform_GetAttributes(test_decoder, &attributes); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_GetUINT32(attributes, &MF_SA_D3D_AWARE, &value); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(value == 1, "got %u\n", value); + IMFAttributes_Release(attributes); + + IMFSourceReaderEx_Release(reader_ex); + + fail_request_sample = FALSE; + test_decoder_set_next_output(test_decoder, S_OK); + + sample = (void *)0xdeadbeef; + index = flags = timestamp = 0xdeadbeef; + hr = IMFSourceReader_ReadSample(reader, 0, 0, &index, &flags, ×tamp, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(index == 0, "got %lu.\n", index); + ok(flags == 0, "got %lu.\n", flags); + ok(timestamp == 0, "got %I64d.\n", timestamp); + ok(sample != (void *)0xdeadbeef, "got %p.\n", sample); + + hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_interface(buffer, &IID_IMF2DBuffer2, TRUE); + check_interface(buffer, &IID_IMFGetService, TRUE); + check_interface(buffer, &IID_IMFDXGIBuffer, FALSE); + check_service_interface(buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, TRUE); + IMFMediaBuffer_Release(buffer); + + IMFSample_Release(sample); + + fail_request_sample = TRUE; + + IMFTransform_Release(test_decoder); + IMFSourceReader_Release(reader); + + + /* test d3d aware decoder that allocates buffers */ + + test_decoder_allocate_samples = TRUE; + + hr = MFCreateAttributes(&attributes, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUINT32(attributes, &MF_SOURCE_READER_ENABLE_ADVANCED_VIDEO_PROCESSING, 1); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUnknown(attributes, &MF_SOURCE_READER_D3D_MANAGER, (IUnknown *)d3d9_manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, test_stream_type_desc, -1); + hr = MFCreateStreamDescriptor(0, 1, &media_type, &video_stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + + source = create_test_source(&video_stream, 1); + ok(!!source, "Failed to create test source.\n"); + IMFStreamDescriptor_Release(video_stream); + + hr = MFCreateSourceReaderFromMediaSource(source, attributes, &reader); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFAttributes_Release(attributes); + IMFMediaSource_Release(source); + + hr = IMFSourceReader_SetStreamSelection(reader, 0, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateMediaType(&media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(media_type, rgb32_stream_type_desc, -1); + hr = IMFSourceReader_SetCurrentMediaType(reader, 0, NULL, media_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFMediaType_Release(media_type); + todo_wine ok(!!test_decoder_got_d3d_manager, "d3d manager not received\n"); + + + hr = IMFSourceReader_QueryInterface(reader, &IID_IMFSourceReaderEx, (void **)&reader_ex); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFSourceReaderEx_GetTransformForStream(reader_ex, 0, 0, NULL, &test_decoder); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(test_decoder->lpVtbl == &test_decoder_vtbl, "got unexpected transform\n"); + IMFSourceReaderEx_Release(reader_ex); + + fail_request_sample = FALSE; + test_decoder_set_next_output(test_decoder, S_OK); + + sample = (void *)0xdeadbeef; + index = flags = timestamp = 0xdeadbeef; + hr = IMFSourceReader_ReadSample(reader, 0, 0, &index, &flags, ×tamp, &sample); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(index == 0, "got %lu.\n", index); + ok(flags == 0, "got %lu.\n", flags); + ok(timestamp == 0, "got %I64d.\n", timestamp); + ok(sample != (void *)0xdeadbeef, "got %p.\n", sample); + + /* the buffer we received is a D3D buffer nonetheless */ + hr = IMFSample_GetBufferByIndex(sample, 0, &buffer); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + check_interface(buffer, &IID_IMF2DBuffer2, TRUE); + check_interface(buffer, &IID_IMFGetService, TRUE); + check_interface(buffer, &IID_IMFDXGIBuffer, FALSE); + check_service_interface(buffer, &MR_BUFFER_SERVICE, &IID_IDirect3DSurface9, TRUE); + IMFMediaBuffer_Release(buffer); + + IMFSample_Release(sample); + + fail_request_sample = TRUE; + + IMFTransform_Release(test_decoder); + IMFSourceReader_Release(reader); + + test_decoder_allocate_samples = FALSE; + + + hr = MFTUnregisterLocal(&factory); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IDirect3DDeviceManager9_Release(d3d9_manager); + IDirect3DDevice9_Release(d3d9_device); + +done: + IDirect3D9_Release(d3d9); + DestroyWindow(window); + + test_decoder_d3d_aware = FALSE; +} + START_TEST(mfplat) { HRESULT hr; @@ -2796,6 +3180,7 @@ START_TEST(mfplat) test_source_reader_transforms(TRUE, FALSE); test_source_reader_transforms(FALSE, TRUE); test_source_reader_transform_stream_change(); + test_source_reader_transforms_d3d(); test_reader_d3d9(); test_sink_writer_create(); test_sink_writer_mp4();
Actually, drop the new helper, I started by splitting it thinking that using MFTEnumEx would cause more code, but it's actually quite similar. Not changing it makes the diff smaller.
Anything I should do here?
Nikolay Sivov (@nsivov) commented about dlls/mfreadwrite/reader.c:
} count = 0;
- if (SUCCEEDED(hr = MFTEnum(category, 0, &in_type, allow_processor ? NULL : &out_type, NULL, &classes, &count)))
- if (SUCCEEDED(hr = MFTEnumEx(category, 0, &in_type, allow_processor ? NULL : &out_type, &activates, &count)))
You mentioned locally registered components in tests, but are they actually enumerated on Windows by the reader?
Nikolay Sivov (@nsivov) commented about dlls/mfreadwrite/tests/Makefile.in:
TESTDLL = mfreadwrite.dll -IMPORTS = ole32 user32 d3d9 dxva2 mfplat mfreadwrite mfuuid propsys +IMPORTS = ole32 user32 d3d9 dxva2 mfplat mf mfreadwrite mfuuid propsys
No real reason to use mf.dll from this one. Is this for MFGetService() only? It works for tests of course, but I tried to keep unrelated parts separate from each other.
On Tue Apr 2 11:11:58 2024 +0000, Nikolay Sivov wrote:
You mentioned locally registered components in tests, but are they actually enumerated on Windows by the reader?
Well yes, otherwise the tests wouldn't work?
On Tue Apr 2 11:11:59 2024 +0000, Nikolay Sivov wrote:
No real reason to use mf.dll from this one. Is this for MFGetService() only? It works for tests of course, but I tried to keep unrelated parts separate from each other.
Not completely sure anymore but I think, yes. I can probably call the interface manually if that matters.
On Tue Apr 2 11:14:58 2024 +0000, Rémi Bernon wrote:
Well yes, otherwise the tests wouldn't work?
Ah, sorry, that makes sense.
On Tue Apr 2 11:15:57 2024 +0000, Rémi Bernon wrote:
Not completely sure anymore but I think, yes. I can probably call the interface manually if that matters.
That's up to you.
This merge request was approved by Nikolay Sivov.