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.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/reader.c | 66 ++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 25 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index b77b5f9c538..6fabc482f0a 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1921,6 +1921,43 @@ static BOOL source_reader_allow_video_processor(struct source_reader *reader, BO return *advanced; }
+static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL decoder, BOOL allow_processor, + IMFMediaType *input_type, IMFMediaType *output_type, struct transform_entry **out); + +static HRESULT source_reader_connect_transform(struct source_reader *reader, BOOL allow_processor, + IMFMediaType *input_type, IMFMediaType *output_type, IMFTransform *transform, + struct transform_entry *entry) +{ + IMFMediaType *media_type; + HRESULT hr; + + if (SUCCEEDED(hr = IMFTransform_SetInputType(transform, 0, input_type, 0)) + && SUCCEEDED(hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type))) + { + if (SUCCEEDED(hr = update_media_type_from_upstream(output_type, media_type)) + && FAILED(hr = IMFTransform_SetOutputType(transform, 0, output_type, 0)) && allow_processor + && SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type))) + { + struct transform_entry *converter; + + if (SUCCEEDED(hr = IMFTransform_SetOutputType(transform, 0, media_type, 0)) + && SUCCEEDED(hr = update_media_type_from_upstream(output_type, media_type)) + && SUCCEEDED(hr = source_reader_create_transform(reader, FALSE, FALSE, media_type, output_type, &converter))) + list_add_tail(&entry->entry, &converter->entry); + + IMFMediaType_Release(media_type); + } + + if (SUCCEEDED(hr)) + { + entry->transform = transform; + return S_OK; + } + } + + return hr; +} + static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL decoder, BOOL allow_processor, IMFMediaType *input_type, IMFMediaType *output_type, struct transform_entry **out) { @@ -1970,35 +2007,14 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL
for (i = 0; i < count; i++) { - IMFMediaType *media_type; - if (FAILED(hr = CoCreateInstance(&classes[i], NULL, CLSCTX_INPROC_SERVER, &IID_IMFTransform, (void **)&transform))) break; - if (SUCCEEDED(hr = IMFTransform_SetInputType(transform, 0, input_type, 0)) - && SUCCEEDED(hr = IMFTransform_GetInputCurrentType(transform, 0, &media_type))) + if (SUCCEEDED(hr = source_reader_connect_transform(reader, allow_processor, input_type, output_type, transform, entry))) { - if (SUCCEEDED(hr = update_media_type_from_upstream(output_type, media_type)) - && FAILED(hr = IMFTransform_SetOutputType(transform, 0, output_type, 0)) && allow_processor - && SUCCEEDED(hr = IMFTransform_GetOutputAvailableType(transform, 0, 0, &media_type))) - { - struct transform_entry *converter; - - if (SUCCEEDED(hr = IMFTransform_SetOutputType(transform, 0, media_type, 0)) - && SUCCEEDED(hr = update_media_type_from_upstream(output_type, media_type)) - && SUCCEEDED(hr = source_reader_create_transform(reader, FALSE, FALSE, media_type, output_type, &converter))) - list_add_tail(&entry->entry, &converter->entry); - - IMFMediaType_Release(media_type); - } - - if (SUCCEEDED(hr)) - { - entry->transform = transform; - *out = entry; - return S_OK; - } + *out = entry; + entry = NULL; + break; } - IMFTransform_Release(transform); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfreadwrite/reader.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/dlls/mfreadwrite/reader.c b/dlls/mfreadwrite/reader.c index 6fabc482f0a..c9d20ca213c 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -1963,7 +1963,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; @@ -1997,7 +1998,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) { @@ -2007,8 +2008,8 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL
for (i = 0; i < count; i++) { - 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 = source_reader_connect_transform(reader, allow_processor, input_type, output_type, transform, entry))) { *out = entry; @@ -2018,7 +2019,9 @@ static HRESULT source_reader_create_transform(struct source_reader *reader, BOOL IMFTransform_Release(transform); }
- CoTaskMemFree(classes); + for (i = 0; i < count; ++i) + IMFActivate_Release(activates[i]); + CoTaskMemFree(activates); }
free(entry);
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 c9d20ca213c..1adcbbcec2c 100644 --- a/dlls/mfreadwrite/reader.c +++ b/dlls/mfreadwrite/reader.c @@ -2527,6 +2527,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) @@ -2540,7 +2543,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();
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=144441
Your paranoid android.
=== debian11 (32 bit report) ===
mfreadwrite: Unhandled exception: assertion failed in 32-bit code (0xf7faf559).
Report validation errors: mfreadwrite:mfplat has unaccounted for todo messages mfreadwrite:mfplat prints too much data (53621 bytes) mfreadwrite:mfplat returned success despite having failures
=== debian11b (32 bit WoW report) ===
mfreadwrite: mfplat: Timeout