This shows that media session samples are correctly oriented, but that mfmediaengine renders them upside down.
-- v4: mfmediaengine: Remove vertical flipping of video frames. mfmediaengine/tests: Check IMFMediaEngine_TransferVideoFrames output orientation. mfmediaengine/tests: Pass a device and output format to create_media_engine. mf/tests: Check sample grabber RGB / NV12 orientation. mf/tests: Factor test grabber callback implementations.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 159 ++++++++++++++++----------------------------- 1 file changed, 56 insertions(+), 103 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 14b75d52fc2..28e62b858d8 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -2543,8 +2543,18 @@ static void test_media_session_rate_control(void) ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr); }
-static HRESULT WINAPI test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid, - void **obj) +struct test_grabber_callback +{ + IMFSampleGrabberSinkCallback IMFSampleGrabberSinkCallback_iface; + LONG refcount; +}; + +static struct test_grabber_callback *impl_from_IMFSampleGrabberSinkCallback(IMFSampleGrabberSinkCallback *iface) +{ + return CONTAINING_RECORD(iface, struct test_grabber_callback, IMFSampleGrabberSinkCallback_iface); +} + +static HRESULT WINAPI test_grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid, void **obj) { if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) || IsEqualIID(riid, &IID_IMFClockStateSink) || @@ -2561,36 +2571,42 @@ static HRESULT WINAPI test_grabber_callback_QueryInterface(IMFSampleGrabberSinkC
static ULONG WINAPI test_grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface) { - return 2; + struct test_grabber_callback *grabber = impl_from_IMFSampleGrabberSinkCallback(iface); + return InterlockedIncrement(&grabber->refcount); }
static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback *iface) { - return 1; + struct test_grabber_callback *grabber = impl_from_IMFSampleGrabberSinkCallback(iface); + ULONG refcount = InterlockedDecrement(&grabber->refcount); + + if (!refcount) + free(grabber); + + return refcount; }
-static HRESULT WINAPI test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME systime, - LONGLONG offset) +static HRESULT WINAPI test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME time, LONGLONG offset) { return E_NOTIMPL; }
-static HRESULT WINAPI test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME systime) +static HRESULT WINAPI test_grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME time) { return E_NOTIMPL; }
-static HRESULT WINAPI test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME systime) +static HRESULT WINAPI test_grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME time) { return E_NOTIMPL; }
-static HRESULT WINAPI test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME systime) +static HRESULT WINAPI test_grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME time) { return E_NOTIMPL; }
-static HRESULT WINAPI test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME systime, float rate) +static HRESULT WINAPI test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME time, float rate) { return E_NOTIMPL; } @@ -2598,7 +2614,7 @@ static HRESULT WINAPI test_grabber_callback_OnClockSetRate(IMFSampleGrabberSinkC static HRESULT WINAPI test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface, IMFPresentationClock *clock) { - return E_NOTIMPL; + return S_OK; }
static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type, @@ -2609,7 +2625,7 @@ static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSink
static HRESULT WINAPI test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface) { - return E_NOTIMPL; + return S_OK; }
static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl = @@ -2627,6 +2643,19 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl = test_grabber_callback_OnShutdown, };
+static IMFSampleGrabberSinkCallback *create_test_grabber_callback(void) +{ + struct test_grabber_callback *grabber; + + if (!(grabber = calloc(1, sizeof(*grabber)))) + return NULL; + + grabber->IMFSampleGrabberSinkCallback_iface.lpVtbl = &test_grabber_callback_vtbl; + grabber->refcount = 1; + + return &grabber->IMFSampleGrabberSinkCallback_iface; +} + enum loader_test_flags { LOADER_EXPECTED_DECODER = 0x1, @@ -2927,8 +2956,8 @@ static void test_topology_loader(void) }, };
- IMFSampleGrabberSinkCallback test_grabber_callback = { &test_grabber_callback_vtbl }; IMFTopologyNode *src_node, *sink_node, *src_node2, *sink_node2, *mft_node; + IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); struct test_stream_sink stream_sink = test_stream_sink; IMFMediaType *media_type, *input_type, *output_type; IMFTopology *topology, *topology2, *full_topology; @@ -3013,7 +3042,7 @@ static void test_topology_loader(void) hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
- hr = MFCreateSampleGrabberSinkActivate(media_type, &test_grabber_callback, &sink_activate); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &sink_activate); ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr);
hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate); @@ -3347,6 +3376,8 @@ todo_wine {
hr = MFShutdown(); ok(hr == S_OK, "Shutdown failure, hr %#lx.\n", hr); + + IMFSampleGrabberSinkCallback_Release(grabber_callback); }
static void test_topology_loader_evr(void) @@ -3932,92 +3963,9 @@ static void test_presentation_clock(void) ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); }
-static HRESULT WINAPI grabber_callback_QueryInterface(IMFSampleGrabberSinkCallback *iface, REFIID riid, void **obj) -{ - if (IsEqualIID(riid, &IID_IMFSampleGrabberSinkCallback) || - IsEqualIID(riid, &IID_IMFClockStateSink) || - IsEqualIID(riid, &IID_IUnknown)) - { - *obj = iface; - IMFSampleGrabberSinkCallback_AddRef(iface); - return S_OK; - } - - *obj = NULL; - return E_NOINTERFACE; -} - -static ULONG WINAPI grabber_callback_AddRef(IMFSampleGrabberSinkCallback *iface) -{ - return 2; -} - -static ULONG WINAPI grabber_callback_Release(IMFSampleGrabberSinkCallback *iface) -{ - return 1; -} - -static HRESULT WINAPI grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME time, LONGLONG offset) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI grabber_callback_OnClockStop(IMFSampleGrabberSinkCallback *iface, MFTIME time) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI grabber_callback_OnClockPause(IMFSampleGrabberSinkCallback *iface, MFTIME time) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI grabber_callback_OnClockRestart(IMFSampleGrabberSinkCallback *iface, MFTIME time) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI grabber_callback_OnClockSetRate(IMFSampleGrabberSinkCallback *iface, MFTIME time, float rate) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface, - IMFPresentationClock *clock) -{ - return S_OK; -} - -static HRESULT WINAPI grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type, - DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size) -{ - return E_NOTIMPL; -} - -static HRESULT WINAPI grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface) -{ - return S_OK; -} - -static const IMFSampleGrabberSinkCallbackVtbl grabber_callback_vtbl = -{ - grabber_callback_QueryInterface, - grabber_callback_AddRef, - grabber_callback_Release, - grabber_callback_OnClockStart, - grabber_callback_OnClockStop, - grabber_callback_OnClockPause, - grabber_callback_OnClockRestart, - grabber_callback_OnClockSetRate, - grabber_callback_OnSetPresentationClock, - grabber_callback_OnProcessSample, - grabber_callback_OnShutdown, -}; - -static IMFSampleGrabberSinkCallback grabber_callback = { &grabber_callback_vtbl }; - static void test_sample_grabber(void) { + IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); IMFMediaType *media_type, *media_type2, *media_type3; IMFMediaTypeHandler *handler, *handler2; IMFPresentationTimeSource *time_source; @@ -4044,7 +3992,7 @@ static void test_sample_grabber(void) hr = MFCreateSampleGrabberSinkActivate(NULL, NULL, &activate); ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
- hr = MFCreateSampleGrabberSinkActivate(NULL, &grabber_callback, &activate); + hr = MFCreateSampleGrabberSinkActivate(NULL, grabber_callback, &activate); ok(hr == E_POINTER, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaType_SetGUID(media_type, &MF_MT_MAJOR_TYPE, &MFMediaType_Audio); @@ -4053,7 +4001,7 @@ static void test_sample_grabber(void) ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
EXPECT_REF(media_type, 1); - hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &activate); ok(hr == S_OK, "Failed to create grabber activate, hr %#lx.\n", hr); EXPECT_REF(media_type, 2);
@@ -4411,7 +4359,7 @@ static void test_sample_grabber(void) hr = IMFMediaType_SetGUID(media_type, &MF_MT_SUBTYPE, &MFAudioFormat_PCM); ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
- hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &activate); ok(hr == S_OK, "Failed to create grabber activate, hr %#lx.\n", hr);
hr = IMFActivate_SetUINT32(activate, &MF_SAMPLEGRABBERSINK_IGNORE_CLOCK, 1); @@ -4437,7 +4385,7 @@ static void test_sample_grabber(void) ok(ref == 0, "Release returned %ld\n", ref);
/* Detaching */ - hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &activate); ok(hr == S_OK, "Failed to create grabber activate, hr %#lx.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); @@ -4470,10 +4418,13 @@ static void test_sample_grabber(void)
hr = MFShutdown(); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); + + IMFSampleGrabberSinkCallback_Release(grabber_callback); }
static void test_sample_grabber_is_mediatype_supported(void) { + IMFSampleGrabberSinkCallback *grabber_callback = create_test_grabber_callback(); IMFMediaType *media_type, *media_type2, *media_type3; IMFMediaTypeHandler *handler; IMFActivate *activate; @@ -4494,7 +4445,7 @@ static void test_sample_grabber_is_mediatype_supported(void) hr = IMFMediaType_SetUINT32(media_type, &MF_MT_AUDIO_SAMPLES_PER_SECOND, 44100); ok(hr == S_OK, "Failed to set attribute, hr %#lx.\n", hr);
- hr = MFCreateSampleGrabberSinkActivate(media_type, &grabber_callback, &activate); + hr = MFCreateSampleGrabberSinkActivate(media_type, grabber_callback, &activate); ok(hr == S_OK, "Failed to create grabber activate, hr %#lx.\n", hr);
hr = IMFActivate_ActivateObject(activate, &IID_IMFMediaSink, (void **)&sink); @@ -4583,6 +4534,8 @@ static void test_sample_grabber_is_mediatype_supported(void) ok(ref == 0, "Release returned %ld\n", ref); ref = IMFMediaType_Release(media_type); ok(ref == 0, "Release returned %ld\n", ref); + + IMFSampleGrabberSinkCallback_Release(grabber_callback); }
static void test_quality_manager(void)
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 267 ++++++++++++++++++++++++++- dlls/mf/tests/mf_test.h | 43 ++++- dlls/mf/tests/nv12frame-grabber.bmp | Bin 0 -> 22582 bytes dlls/mf/tests/resource.rc | 17 ++ dlls/mf/tests/rgb32frame-grabber.bmp | Bin 0 -> 16438 bytes dlls/mf/tests/test.mp4 | Bin 0 -> 3983 bytes dlls/mf/tests/transform.c | 100 ++++------ 7 files changed, 361 insertions(+), 66 deletions(-) create mode 100644 dlls/mf/tests/nv12frame-grabber.bmp create mode 100644 dlls/mf/tests/rgb32frame-grabber.bmp create mode 100644 dlls/mf/tests/test.mp4
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 28e62b858d8..c9f8fe96f8b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -102,6 +102,36 @@ static HWND create_window(void) 0, 0, r.right - r.left, r.bottom - r.top, NULL, NULL, NULL, NULL); }
+static IMFSample *create_sample(const BYTE *data, ULONG size) +{ + IMFMediaBuffer *media_buffer; + IMFSample *sample; + DWORD length; + BYTE *buffer; + HRESULT hr; + ULONG ret; + + hr = MFCreateSample(&sample); + ok(hr == S_OK, "MFCreateSample returned %#lx\n", hr); + hr = MFCreateMemoryBuffer(size, &media_buffer); + ok(hr == S_OK, "MFCreateMemoryBuffer returned %#lx\n", hr); + hr = IMFMediaBuffer_Lock(media_buffer, &buffer, NULL, &length); + ok(hr == S_OK, "Lock returned %#lx\n", hr); + ok(length == 0, "got length %lu\n", length); + if (!data) memset(buffer, 0xcd, size); + else memcpy(buffer, data, size); + hr = IMFMediaBuffer_Unlock(media_buffer); + ok(hr == S_OK, "Unlock returned %#lx\n", hr); + hr = IMFMediaBuffer_SetCurrentLength(media_buffer, data ? size : 0); + ok(hr == S_OK, "SetCurrentLength returned %#lx\n", hr); + hr = IMFSample_AddBuffer(sample, media_buffer); + ok(hr == S_OK, "AddBuffer returned %#lx\n", hr); + ret = IMFMediaBuffer_Release(media_buffer); + ok(ret == 1, "Release returned %lu\n", ret); + + return sample; +} + #define check_handler_required_attributes(a, b) check_handler_required_attributes_(__LINE__, a, b) static void check_handler_required_attributes_(int line, IMFMediaTypeHandler *handler, const struct attribute_desc *attributes) { @@ -1879,6 +1909,51 @@ static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCal return status; }
+static IMFMediaSource *create_media_source(const WCHAR *name, const WCHAR *mime) +{ + IMFSourceResolver *resolver; + IMFAttributes *attributes; + const BYTE *resource_data; + MF_OBJECT_TYPE obj_type; + IMFMediaSource *source; + IMFByteStream *stream; + ULONG resource_len; + HRSRC resource; + HRESULT hr; + + resource = FindResourceW(NULL, name, (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW %s failed, error %lu\n", debugstr_w(name), GetLastError()); + resource_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + resource_len = SizeofResource(GetModuleHandleW(NULL), resource); + + hr = MFCreateTempFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_Write(stream, resource_data, resource_len, &resource_len); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_SetCurrentPosition(stream, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, mime); + ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr); + IMFAttributes_Release(attributes); + + hr = MFCreateSourceResolver(&resolver); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFSourceResolver_CreateObjectFromByteStream(resolver, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, + &obj_type, (IUnknown **)&source); + ok(hr == S_OK || broken(hr == MF_E_UNSUPPORTED_BYTESTREAM_TYPE), "Unexpected hr %#lx.\n", hr); + IMFSourceResolver_Release(resolver); + IMFByteStream_Release(stream); + + if (FAILED(hr)) + return NULL; + + ok(obj_type == MF_OBJECT_MEDIASOURCE, "got %d\n", obj_type); + return source; +} + static void test_media_session_events(void) { static const media_type_desc audio_float_44100 = @@ -2547,6 +2622,10 @@ struct test_grabber_callback { IMFSampleGrabberSinkCallback IMFSampleGrabberSinkCallback_iface; LONG refcount; + + IMFCollection *samples; + HANDLE ready_event; + HANDLE done_event; };
static struct test_grabber_callback *impl_from_IMFSampleGrabberSinkCallback(IMFSampleGrabberSinkCallback *iface) @@ -2581,7 +2660,14 @@ static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback * ULONG refcount = InterlockedDecrement(&grabber->refcount);
if (!refcount) + { + IMFCollection_Release(grabber->samples); + if (grabber->ready_event) + CloseHandle(grabber->ready_event); + if (grabber->done_event) + CloseHandle(grabber->done_event); free(grabber); + }
return refcount; } @@ -2620,7 +2706,30 @@ static HRESULT WINAPI test_grabber_callback_OnSetPresentationClock(IMFSampleGrab static HRESULT WINAPI test_grabber_callback_OnProcessSample(IMFSampleGrabberSinkCallback *iface, REFGUID major_type, DWORD sample_flags, LONGLONG sample_time, LONGLONG sample_duration, const BYTE *buffer, DWORD sample_size) { - return E_NOTIMPL; + struct test_grabber_callback *grabber = CONTAINING_RECORD(iface, struct test_grabber_callback, IMFSampleGrabberSinkCallback_iface); + IMFSample *sample; + HRESULT hr; + DWORD res; + + if (!grabber->ready_event) + return E_NOTIMPL; + + sample = create_sample(buffer, sample_size); + hr = IMFSample_SetSampleFlags(sample, sample_flags); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + /* FIXME: sample time is inconsistent across windows versions, ignore it */ + hr = IMFSample_SetSampleTime(sample, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFSample_SetSampleDuration(sample, sample_duration); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFCollection_AddElement(grabber->samples, (IUnknown *)sample); + IMFSample_Release(sample); + + SetEvent(grabber->ready_event); + res = WaitForSingleObject(grabber->done_event, 1000); + ok(!res, "WaitForSingleObject returned %#lx", res); + + return S_OK; }
static HRESULT WINAPI test_grabber_callback_OnShutdown(IMFSampleGrabberSinkCallback *iface) @@ -2646,12 +2755,15 @@ static const IMFSampleGrabberSinkCallbackVtbl test_grabber_callback_vtbl = static IMFSampleGrabberSinkCallback *create_test_grabber_callback(void) { struct test_grabber_callback *grabber; + HRESULT hr;
if (!(grabber = calloc(1, sizeof(*grabber)))) return NULL;
grabber->IMFSampleGrabberSinkCallback_iface.lpVtbl = &test_grabber_callback_vtbl; grabber->refcount = 1; + hr = MFCreateCollection(&grabber->samples); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
return &grabber->IMFSampleGrabberSinkCallback_iface; } @@ -4538,6 +4650,157 @@ static void test_sample_grabber_is_mediatype_supported(void) IMFSampleGrabberSinkCallback_Release(grabber_callback); }
+static void test_sample_grabber_orientation(GUID subtype) +{ + media_type_desc video_rgb32_desc = + { + ATTR_GUID(MF_MT_MAJOR_TYPE, MFMediaType_Video), + ATTR_GUID(MF_MT_SUBTYPE, subtype), + }; + + struct test_grabber_callback *grabber_callback; + IMFTopologyNode *src_node, *sink_node; + IMFPresentationDescriptor *pd; + IMFAsyncCallback *callback; + IMFActivate *sink_activate; + IMFMediaType *output_type; + IMFMediaSession *session; + IMFStreamDescriptor *sd; + IMFMediaSource *source; + IMFTopology *topology; + PROPVARIANT propvar; + BOOL selected; + HRESULT hr; + DWORD res; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Failed to start up, hr %#lx.\n", hr); + + if (!(source = create_media_source(L"test.mp4", L"video/mp4"))) + { + win_skip("MP4 media source is not supported, skipping tests.\n"); + return; + } + + callback = create_test_callback(); + grabber_callback = impl_from_IMFSampleGrabberSinkCallback(create_test_grabber_callback()); + + grabber_callback->ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!grabber_callback->ready_event, "CreateEventW failed, error %lu\n", GetLastError()); + grabber_callback->done_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!grabber_callback->done_event, "CreateEventW failed, error %lu\n", GetLastError()); + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "Startup failure, hr %#lx.\n", hr); + + hr = MFCreateMediaSession(NULL, &session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = MFCreateTopology(&topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology, sink_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopology_AddNode(topology, src_node); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); + ok(selected, "got selected %u.\n", !!selected); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_source_node(source, -1, src_node, pd, sd); + IMFTopologyNode_Release(src_node); + IMFPresentationDescriptor_Release(pd); + IMFStreamDescriptor_Release(sd); + + hr = MFCreateMediaType(&output_type); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + init_media_type(output_type, video_rgb32_desc, -1); + hr = MFCreateSampleGrabberSinkActivate(output_type, &grabber_callback->IMFSampleGrabberSinkCallback_iface, &sink_activate); + ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); + IMFMediaType_Release(output_type); + + hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate); + ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr); + hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_ALLOW_DECODER); + ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr); + IMFTopologyNode_Release(sink_node); + + hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, TRUE); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaSession_SetTopology(session, 0, topology); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFTopology_Release(topology); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + res = WaitForSingleObject(grabber_callback->ready_event, 5000); + ok(!res, "WaitForSingleObject returned %#lx\n", res); + CloseHandle(grabber_callback->ready_event); + grabber_callback->ready_event = NULL; + + if (IsEqualGUID(&subtype, &MFVideoFormat_RGB32)) + { + const struct buffer_desc buffer_desc_rgb32 = + { + .length = 64 * 64 * 4, .compare = compare_rgb32, .dump = dump_rgb32, .rect = {.right = 64, .bottom = 64}, + }; + const struct sample_desc sample_desc_rgb32 = + { + .sample_duration = 333667, .buffer_count = 1, .buffers = &buffer_desc_rgb32, + }; + check_mf_sample_collection(grabber_callback->samples, &sample_desc_rgb32, L"rgb32frame-grabber.bmp"); + } + else if (IsEqualGUID(&subtype, &MFVideoFormat_NV12)) + { + const struct buffer_desc buffer_desc_nv12 = + { + .length = 64 * 64 * 3 / 2, .compare = compare_nv12, .dump = dump_nv12, .rect = {.right = 64, .bottom = 64}, + }; + const struct sample_desc sample_desc_nv12 = + { + .sample_duration = 333667, .buffer_count = 1, .buffers = &buffer_desc_nv12, + }; + check_mf_sample_collection(grabber_callback->samples, &sample_desc_nv12, L"nv12frame-grabber.bmp"); + } + + SetEvent(grabber_callback->done_event); + + hr = IMFMediaSession_ClearTopologies(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaSession_Close(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = wait_media_event(session, callback, MESessionClosed, 1000, &propvar); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(propvar.vt == VT_EMPTY, "got vt %u\n", propvar.vt); + + hr = IMFMediaSession_Shutdown(session); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFMediaSource_Shutdown(source); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFActivate_ShutdownObject(sink_activate); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFActivate_Release(sink_activate); + IMFMediaSession_Release(session); + IMFMediaSource_Release(source); + + hr = MFShutdown(); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + IMFSampleGrabberSinkCallback_Release(&grabber_callback->IMFSampleGrabberSinkCallback_iface); +} + static void test_quality_manager(void) { IMFPresentationClock *clock; @@ -6239,6 +6502,8 @@ START_TEST(mf) test_presentation_clock(); test_sample_grabber(); test_sample_grabber_is_mediatype_supported(); + test_sample_grabber_orientation(MFVideoFormat_RGB32); + test_sample_grabber_orientation(MFVideoFormat_NV12); test_quality_manager(); test_sar(); test_evr(); diff --git a/dlls/mf/tests/mf_test.h b/dlls/mf/tests/mf_test.h index d908acb89a4..7973e007a68 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -53,7 +53,44 @@ typedef struct attribute_desc media_type_desc[32]; #define ATTR_RATIO(k, n, d, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.HighPart = n, .LowPart = d}}, .ratio = TRUE, __VA_ARGS__ } #define ATTR_UINT64(k, v, ...) {.key = &k, .name = #k, {.vt = VT_UI8, .uhVal = {.QuadPart = v}}, __VA_ARGS__ }
-#define check_media_type(a, b, c) check_attributes_(__LINE__, (IMFAttributes *)a, b, c) -#define check_attributes(a, b, c) check_attributes_(__LINE__, a, b, c) -extern void check_attributes_(int line, IMFAttributes *attributes, const struct attribute_desc *desc, ULONG limit); +#define check_media_type(a, b, c) check_attributes_(__FILE__, __LINE__, (IMFAttributes *)a, b, c) +#define check_attributes(a, b, c) check_attributes_(__FILE__, __LINE__, a, b, c) +extern void check_attributes_(const char *file, int line, IMFAttributes *attributes, + const struct attribute_desc *desc, ULONG limit); extern void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, ULONG limit); + +typedef DWORD (*compare_cb)(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect); +extern DWORD compare_nv12(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect); +extern DWORD compare_i420(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect); +extern DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect); +extern DWORD compare_pcm16(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect); + +typedef void (*dump_cb)(const BYTE *data, DWORD length, const RECT *rect, HANDLE output); +extern void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output); +extern void dump_nv12(const BYTE *data, DWORD length, const RECT *rect, HANDLE output); +extern void dump_i420(const BYTE *data, DWORD length, const RECT *rect, HANDLE output); + +struct buffer_desc +{ + DWORD length; + BOOL todo_length; + compare_cb compare; + dump_cb dump; + RECT rect; +}; + +struct sample_desc +{ + const struct attribute_desc *attributes; + LONGLONG sample_time; + LONGLONG sample_duration; + DWORD buffer_count; + const struct buffer_desc *buffers; + DWORD repeat_count; + BOOL todo_length; + LONGLONG todo_time; +}; + +#define check_mf_sample_collection(a, b, c) check_mf_sample_collection_(__FILE__, __LINE__, a, b, c) +extern DWORD check_mf_sample_collection_(const char *file, int line, IMFCollection *samples, + const struct sample_desc *expect_samples, const WCHAR *expect_data_filename); diff --git a/dlls/mf/tests/nv12frame-grabber.bmp b/dlls/mf/tests/nv12frame-grabber.bmp new file mode 100644 index 0000000000000000000000000000000000000000..2acd5d9992330c5b71afd7ffb5d34a3770eb1dee GIT binary patch literal 22582 zcmeIwp%H^n5QJe$z~VBf(7@A76ea>o2?%PyBB2Nbr64H)i@?yq<qZ=PeIjE2z1cTd zcD~m;l*yeC-)C(3ZIV3VS4?@oKhN3sM%e%Z7{CAqFd$~28tfGA7XMwk>0}#a0}NmQ z0~o-7l!0YVjj{m-Fn|FJU_i`3m)RoRG5))BLvABw0}NmQ0~o-7l!12Ljj{m-Fn|FJ zU_i{kbXY6gI{v$Ko6Bm-1{lBq1~7mDDFemT8D#?uU;qOczyJm?pkv@9EZ|sRBP`%p zU?D8vSYRY9;8>s~EZ|t6CM@7spdc*p#|3)vRD<u*N&Dth`?}0`A=kcj*S_iSU2|#Q I)p4E$KCEGdKL7v#
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 6cbf64d4528..25768d21983 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -67,6 +67,10 @@ h264data.bin RCDATA h264data.bin /* @makedep: nv12frame.bmp */ nv12frame.bmp RCDATA nv12frame.bmp
+/* Generated from running the tests on Windows */ +/* @makedep: nv12frame-grabber.bmp */ +nv12frame-grabber.bmp RCDATA nv12frame-grabber.bmp + /* Generated from running the tests on Windows */ /* @makedep: i420frame.bmp */ i420frame.bmp RCDATA i420frame.bmp @@ -78,3 +82,16 @@ rgb32frame.bmp RCDATA rgb32frame.bmp /* Generated from running the tests on Windows */ /* @makedep: rgb32frame-vp.bmp */ rgb32frame-vp.bmp RCDATA rgb32frame-vp.bmp + +/* Generated from running the tests on Windows */ +/* @makedep: rgb32frame-grabber.bmp */ +rgb32frame-grabber.bmp RCDATA rgb32frame-grabber.bmp + +/* Generated with: + * gst-launch-1.0 videotestsrc num-buffers=60 pattern=smpte100 ! \ + * video/x-raw,format=I420,width=64,height=64,framerate=30000/1001 ! \ + * videoflip method=clockwise ! videoconvert ! \ + * x264enc ! mp4mux ! filesink location=dlls/mf/tests/test.mp4 + */ +/* @makedep: test.mp4 */ +test.mp4 RCDATA test.mp4 diff --git a/dlls/mf/tests/rgb32frame-grabber.bmp b/dlls/mf/tests/rgb32frame-grabber.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b5a5960b96481bd01a5cc1a1fe9358127ca370bb GIT binary patch literal 16438 zcmeI&JxW7C6o%n9h=OPq5K*x35A0LNprtlhf-6X$CL72CbO&~pqN~s*DT8qVYDCc7 zJ03zB*YKW!XSnS-=NlL<)4gnWSgv;LC!w<f`|%a4v)un}bzPIP2bqD)KxV*~ftOM+ zn@0U+w^6@Y@9P7zi|;vRlnS$Ey}-;o`>eg<u*}r#8F(rK%(|~b%;Nfs+2pr{nR)hE zJG_^Mnmq##WfQZzvW408Cz$QV?+>%nA21{CzbSi=8E|Hxf8WRK`0WU@@y-OZ(bWjE zikg%?$P73$@Vrqlo36$CAF-Qe!K_ET{}DT9ju~<LG23Q=nR)hEd&R-}OwFEw$Grh& dXACi`8(=o3g_(KwS-bn}=lpa2nE`hO{s5dR2pIqX
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/test.mp4 b/dlls/mf/tests/test.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..752d860008d472a1bfb26a1a97ef0c9b36ab2ba5 GIT binary patch literal 3983 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 JJHR;<_)p|_beRAE
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index e66baa6e7c9..edb73ac79e6 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -90,7 +90,8 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO ok_ (file, line)((val).member == (exp).member, "got " #member " " fmt "\n", (val).member) #define check_member(val, exp, fmt, member) check_member_(__FILE__, __LINE__, val, exp, fmt, member)
-void check_attributes_(int line, IMFAttributes *attributes, const struct attribute_desc *desc, ULONG limit) +void check_attributes_(const char *file, int line, IMFAttributes *attributes, + const struct attribute_desc *desc, ULONG limit) { char buffer[256], *buf = buffer; PROPVARIANT value; @@ -101,7 +102,7 @@ void check_attributes_(int line, IMFAttributes *attributes, const struct attribu { hr = IMFAttributes_GetItem(attributes, desc[i].key, &value); todo_wine_if(desc[i].todo) - ok_(__FILE__, line)(hr == S_OK, "%s missing, hr %#lx\n", debugstr_a(desc[i].name), hr); + ok_(file, line)(hr == S_OK, "%s missing, hr %#lx\n", debugstr_a(desc[i].name), hr); if (hr != S_OK) continue;
switch (value.vt) @@ -128,7 +129,7 @@ void check_attributes_(int line, IMFAttributes *attributes, const struct attribu
ret = PropVariantCompareEx(&value, &desc[i].value, 0, 0); todo_wine_if(desc[i].todo_value) - ok_(__FILE__, line)(ret == 0, "%s mismatch, type %u, value %s\n", + ok_(file, line)(ret == 0, "%s mismatch, type %u, value %s\n", debugstr_a(desc[i].name), value.vt, buffer); } } @@ -613,9 +614,7 @@ static HRESULT check_mft_process_output_(int line, IMFTransform *transform, IMFS return ret; }
-typedef DWORD (*compare_cb)(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect); - -static DWORD compare_nv12(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) +DWORD compare_nv12(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
@@ -649,7 +648,7 @@ static DWORD compare_nv12(const BYTE *data, DWORD *length, const RECT *rect, con return diff * 100 / 256 / size; }
-static DWORD compare_i420(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) +DWORD compare_i420(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { DWORD i, x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
@@ -682,7 +681,7 @@ static DWORD compare_i420(const BYTE *data, DWORD *length, const RECT *rect, con return diff * 100 / 256 / size; }
-static DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) +DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf;
@@ -707,7 +706,7 @@ static DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, co return diff * 100 / 256 / size; }
-static DWORD compare_pcm16(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) +DWORD compare_pcm16(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) { const INT16 *data_pcm = (INT16 *)data, *expect_pcm = (INT16 *)expect; DWORD i, size = *length / 2, diff = 0; @@ -728,9 +727,7 @@ static DWORD compare_bytes(const BYTE *data, DWORD *length, const RECT *rect, co return diff * 100 / 256 / size; }
-typedef void (*dump_cb)(const BYTE *data, DWORD length, const RECT *rect, HANDLE output); - -static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) { DWORD width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; static const char magic[2] = "BM"; @@ -763,7 +760,7 @@ static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE ok(written == length, "written %lu bytes\n", written); }
-static void dump_nv12(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +void dump_nv12(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) { DWORD written, x, y, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; BYTE *rgb32_data = malloc(width * height * 4), *rgb32 = rgb32_data; @@ -785,7 +782,7 @@ static void dump_nv12(const BYTE *data, DWORD length, const RECT *rect, HANDLE o ok(written == length, "written %lu bytes\n", written); }
-static void dump_i420(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +void dump_i420(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) { DWORD written, x, y, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; BYTE *rgb32_data = malloc(width * height * 4), *rgb32 = rgb32_data; @@ -807,27 +804,6 @@ static void dump_i420(const BYTE *data, DWORD length, const RECT *rect, HANDLE o ok(written == length, "written %lu bytes\n", written); }
-struct buffer_desc -{ - DWORD length; - BOOL todo_length; - compare_cb compare; - dump_cb dump; - RECT rect; -}; - -struct sample_desc -{ - const struct attribute_desc *attributes; - LONGLONG sample_time; - LONGLONG sample_duration; - DWORD buffer_count; - const struct buffer_desc *buffers; - DWORD repeat_count; - BOOL todo_length; - LONGLONG todo_time; -}; - typedef void (*enum_mf_media_buffers_cb)(IMFMediaBuffer *buffer, const struct buffer_desc *desc, void *context); static void enum_mf_media_buffers(IMFSample *sample, const struct sample_desc *sample_desc, enum_mf_media_buffers_cb callback, void *context) @@ -935,8 +911,8 @@ static void dump_mf_sample_collection(IMFCollection *samples, const struct sampl CloseHandle(output); }
-#define check_mf_media_buffer(a, b, c) check_mf_media_buffer_(__LINE__, a, b, c) -static DWORD check_mf_media_buffer_(int line, IMFMediaBuffer *buffer, const struct buffer_desc *expect, +#define check_mf_media_buffer(a, b, c) check_mf_media_buffer_(__FILE__, __LINE__, a, b, c) +static DWORD check_mf_media_buffer_(const char *file, int line, IMFMediaBuffer *buffer, const struct buffer_desc *expect, const BYTE **expect_data, DWORD *expect_data_len) { DWORD length, diff = 0, expect_length = expect->length; @@ -951,20 +927,20 @@ static DWORD check_mf_media_buffer_(int line, IMFMediaBuffer *buffer, const stru }
hr = IMFMediaBuffer_Lock(buffer, &data, NULL, &length); - ok_(__FILE__, line)(hr == S_OK, "Lock returned %#lx\n", hr); + ok_(file, line)(hr == S_OK, "Lock returned %#lx\n", hr); todo_wine_if(expect->todo_length) - ok_(__FILE__, line)(length == expect_length, "got length %#lx\n", length); + ok_(file, line)(length == expect_length, "got length %#lx\n", length);
if (*expect_data_len < length) todo_wine_if(expect->todo_length) - ok_(__FILE__, line)(0, "missing %#lx bytes\n", length - *expect_data_len); + ok_(file, line)(0, "missing %#lx bytes\n", length - *expect_data_len); else if (!expect->compare) diff = compare_bytes(data, &length, NULL, *expect_data); else diff = expect->compare(data, &length, &expect->rect, *expect_data);
hr = IMFMediaBuffer_Unlock(buffer); - ok_(__FILE__, line)(hr == S_OK, "Unlock returned %#lx\n", hr); + ok_(file, line)(hr == S_OK, "Unlock returned %#lx\n", hr);
*expect_data = *expect_data + min(length, *expect_data_len); *expect_data_len = *expect_data_len - min(length, *expect_data_len); @@ -978,6 +954,7 @@ struct check_mf_sample_context const BYTE *data; DWORD data_len; DWORD diff; + const char *file; int line; };
@@ -985,57 +962,57 @@ static void check_mf_sample_buffer(IMFMediaBuffer *buffer, const struct buffer_d { struct check_mf_sample_context *ctx = context; DWORD expect_length = expect->length == -1 ? *(DWORD *)ctx->data : expect->length; - ctx->diff += check_mf_media_buffer_(ctx->line, buffer, expect, &ctx->data, &ctx->data_len); + ctx->diff += check_mf_media_buffer_(ctx->file, ctx->line, buffer, expect, &ctx->data, &ctx->data_len); ctx->total_length += expect_length; }
-#define check_mf_sample(a, b, c, d) check_mf_sample_(__LINE__, a, b, c, d) -static DWORD check_mf_sample_(int line, IMFSample *sample, const struct sample_desc *expect, +#define check_mf_sample(a, b, c, d) check_mf_sample_(__FILE__, __LINE__, a, b, c, d) +static DWORD check_mf_sample_(const char *file, int line, IMFSample *sample, const struct sample_desc *expect, const BYTE **expect_data, DWORD *expect_data_len) { - struct check_mf_sample_context ctx = {.data = *expect_data, .data_len = *expect_data_len, .line = line}; + struct check_mf_sample_context ctx = {.data = *expect_data, .data_len = *expect_data_len, .file = file, .line = line}; DWORD buffer_count, total_length, sample_flags; LONGLONG timestamp; HRESULT hr;
if (expect->attributes) - check_attributes_(line, (IMFAttributes *)sample, expect->attributes, -1); + check_attributes_(file, line, (IMFAttributes *)sample, expect->attributes, -1);
buffer_count = 0xdeadbeef; hr = IMFSample_GetBufferCount(sample, &buffer_count); - ok_(__FILE__, line)(hr == S_OK, "GetBufferCount returned %#lx\n", hr); - ok_(__FILE__, line)(buffer_count == expect->buffer_count, + ok_(file, line)(hr == S_OK, "GetBufferCount returned %#lx\n", hr); + ok_(file, line)(buffer_count == expect->buffer_count, "got %lu buffers\n", buffer_count);
sample_flags = 0xdeadbeef; hr = IMFSample_GetSampleFlags(sample, &sample_flags); - ok_(__FILE__, line)(hr == S_OK, "GetSampleFlags returned %#lx\n", hr); - ok_(__FILE__, line)(sample_flags == 0, + ok_(file, line)(hr == S_OK, "GetSampleFlags returned %#lx\n", hr); + ok_(file, line)(sample_flags == 0, "got sample flags %#lx\n", sample_flags);
timestamp = 0xdeadbeef; hr = IMFSample_GetSampleTime(sample, ×tamp); - ok_(__FILE__, line)(hr == S_OK, "GetSampleTime returned %#lx\n", hr); + ok_(file, line)(hr == S_OK, "GetSampleTime returned %#lx\n", hr); todo_wine_if(expect->todo_time && timestamp == expect->todo_time) - ok_(__FILE__, line)(llabs(timestamp - expect->sample_time) <= 50, + ok_(file, line)(llabs(timestamp - expect->sample_time) <= 50, "got sample time %I64d\n", timestamp);
timestamp = 0xdeadbeef; hr = IMFSample_GetSampleDuration(sample, ×tamp); - ok_(__FILE__, line)(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); + ok_(file, line)(hr == S_OK, "GetSampleDuration returned %#lx\n", hr); todo_wine_if(expect->todo_length) - ok_(__FILE__, line)(llabs(timestamp - expect->sample_duration) <= 1, + ok_(file, line)(llabs(timestamp - expect->sample_duration) <= 1, "got sample duration %I64d\n", timestamp);
enum_mf_media_buffers(sample, expect, check_mf_sample_buffer, &ctx);
total_length = 0xdeadbeef; hr = IMFSample_GetTotalLength(sample, &total_length); - ok_(__FILE__, line)(hr == S_OK, "GetTotalLength returned %#lx\n", hr); + ok_(file, line)(hr == S_OK, "GetTotalLength returned %#lx\n", hr); todo_wine_if(expect->todo_length) - ok_(__FILE__, line)(total_length == ctx.total_length, + ok_(file, line)(total_length == ctx.total_length, "got total length %#lx\n", total_length); - ok_(__FILE__, line)(*expect_data_len >= ctx.total_length, + ok_(file, line)(*expect_data_len >= ctx.total_length, "missing %#lx data\n", ctx.total_length - *expect_data_len);
*expect_data = ctx.data; @@ -1047,14 +1024,13 @@ static DWORD check_mf_sample_(int line, IMFSample *sample, const struct sample_d static void check_mf_sample_collection_enum(IMFSample *sample, const struct sample_desc *expect, void *context) { struct check_mf_sample_context *ctx = context; - ctx->diff += check_mf_sample_(ctx->line, sample, expect, &ctx->data, &ctx->data_len); + ctx->diff += check_mf_sample_(ctx->file, ctx->line, sample, expect, &ctx->data, &ctx->data_len); }
-#define check_mf_sample_collection(a, b, c) check_mf_sample_collection_(__LINE__, a, b, c) -static DWORD check_mf_sample_collection_(int line, IMFCollection *samples, +DWORD check_mf_sample_collection_(const char *file, int line, IMFCollection *samples, const struct sample_desc *expect_samples, const WCHAR *expect_data_filename) { - struct check_mf_sample_context ctx = {.line = line}; + struct check_mf_sample_context ctx = {.file = file, .line = line}; DWORD count; HRESULT hr;
@@ -1064,7 +1040,7 @@ static DWORD check_mf_sample_collection_(int line, IMFCollection *samples, dump_mf_sample_collection(samples, expect_samples, expect_data_filename);
hr = IMFCollection_GetElementCount(samples, &count); - ok_(__FILE__, line)(hr == S_OK, "GetElementCount returned %#lx\n", hr); + ok_(file, line)(hr == S_OK, "GetElementCount returned %#lx\n", hr);
return ctx.diff / count; }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfmediaengine/tests/mfmediaengine.c | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-)
diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 008ee58849c..3ff81b1f9b1 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -138,7 +138,7 @@ static struct media_engine_notify *create_callback(void) return object; }
-static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback) +static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback, IUnknown *device, UINT32 output_format) { IMFDXGIDeviceManager *manager; IMFMediaEngine *media_engine; @@ -154,7 +154,7 @@ static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback)
hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, (IUnknown *)callback); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); - hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, DXGI_FORMAT_UNKNOWN); + hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, output_format); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
hr = IMFMediaEngineClassFactory_CreateInstance(factory, 0, attributes, &media_engine); @@ -166,9 +166,9 @@ static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback) return media_engine; }
-static IMFMediaEngineEx *create_media_engine_ex(IMFMediaEngineNotify *callback) +static IMFMediaEngineEx *create_media_engine_ex(IMFMediaEngineNotify *callback, IUnknown *device, UINT32 output_format) { - IMFMediaEngine *engine = create_media_engine(callback); + IMFMediaEngine *engine = create_media_engine(callback, device, output_format); IMFMediaEngineEx *engine_ex = NULL;
if (engine) @@ -331,7 +331,7 @@ static void test_Shutdown(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN);
hr = IMFMediaEngine_Shutdown(media_engine); ok(hr == S_OK, "Failed to shut down, hr %#lx.\n", hr); @@ -518,7 +518,7 @@ static void test_Play(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN);
hr = IMFMediaEngine_GetBuffered(media_engine, &range); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -567,7 +567,7 @@ static void test_Play(void) IMFMediaEngine_Release(media_engine);
/* Play -> Pause */ - media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN);
hr = IMFMediaEngine_Play(media_engine); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); @@ -594,7 +594,7 @@ static void test_playback_rate(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN);
rate = IMFMediaEngine_GetDefaultPlaybackRate(media_engine); ok(rate == 1.0, "Unexpected default rate.\n"); @@ -624,7 +624,7 @@ static void test_mute(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN);
ret = IMFMediaEngine_GetMuted(media_engine); ok(!ret, "Unexpected state.\n"); @@ -655,7 +655,7 @@ static void test_error(void)
notify = create_callback();
- media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN);
eo = (void *)0xdeadbeef; hr = IMFMediaEngine_GetError(media_engine, &eo); @@ -917,7 +917,7 @@ static void test_SetSourceFromByteStream(void)
notify = create_callback();
- media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); if (!media_engine) { win_skip("IMFMediaEngineEx is not supported.\n"); @@ -953,7 +953,7 @@ static void test_audio_configuration(void)
notify = create_callback();
- media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface); + media_engine = create_media_engine_ex(¬ify->IMFMediaEngineNotify_iface, NULL, DXGI_FORMAT_UNKNOWN); if (!media_engine) { IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfmediaengine/tests/Makefile.in | 2 + dlls/mfmediaengine/tests/mfmediaengine.c | 345 ++++++++++++++++++++++- dlls/mfmediaengine/tests/resource.rc | 32 +++ dlls/mfmediaengine/tests/rgb32frame.bmp | Bin 0 -> 16438 bytes dlls/mfmediaengine/tests/test.mp4 | Bin 0 -> 3983 bytes 5 files changed, 377 insertions(+), 2 deletions(-) create mode 100644 dlls/mfmediaengine/tests/resource.rc create mode 100644 dlls/mfmediaengine/tests/rgb32frame.bmp create mode 100644 dlls/mfmediaengine/tests/test.mp4
diff --git a/dlls/mfmediaengine/tests/Makefile.in b/dlls/mfmediaengine/tests/Makefile.in index 421b75587a0..b23d530d46f 100644 --- a/dlls/mfmediaengine/tests/Makefile.in +++ b/dlls/mfmediaengine/tests/Makefile.in @@ -3,3 +3,5 @@ IMPORTS = ole32 mfplat oleaut32 mfuuid uuid
C_SRCS = \ mfmediaengine.c + +RC_SRCS = resource.rc diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 3ff81b1f9b1..1b1f60742af 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -28,6 +28,7 @@ #include "mfmediaengine.h" #include "mferror.h" #include "dxgi.h" +#include "d3d11.h" #include "initguid.h" #include "mmdeviceapi.h" #include "audiosessiontypes.h" @@ -35,6 +36,9 @@ #include "wine/test.h"
static HRESULT (WINAPI *pMFCreateDXGIDeviceManager)(UINT *token, IMFDXGIDeviceManager **manager); +static HRESULT (WINAPI *pD3D11CreateDevice)(IDXGIAdapter *adapter, D3D_DRIVER_TYPE driver_type, HMODULE swrast, UINT flags, + const D3D_FEATURE_LEVEL *feature_levels, UINT levels, UINT sdk_version, ID3D11Device **device_out, + D3D_FEATURE_LEVEL *obtained_feature_level, ID3D11DeviceContext **immediate_context);
static IMFMediaEngineClassFactory *factory;
@@ -62,12 +66,104 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO IUnknown_Release(unk); }
+static DWORD compare_rgb32(const BYTE *data, DWORD *length, const RECT *rect, const BYTE *expect) +{ + DWORD x, y, size, diff = 0, width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + + /* skip BMP header from the dump */ + size = *(DWORD *)(expect + 2 + 2 * sizeof(DWORD)); + *length = *length + size; + expect = expect + size; + + for (y = 0; y < height; y++, data += width * 4, expect += width * 4) + { + if (y < rect->top || y >= rect->bottom) continue; + for (x = 0; x < width; x++) + { + if (x < rect->left || x >= rect->right) continue; + diff += abs((int)expect[4 * x + 0] - (int)data[4 * x + 0]); + diff += abs((int)expect[4 * x + 1] - (int)data[4 * x + 1]); + diff += abs((int)expect[4 * x + 2] - (int)data[4 * x + 2]); + } + } + + size = (rect->right - rect->left) * (rect->bottom - rect->top) * 3; + return diff * 100 / 256 / size; +} + +static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE output) +{ + DWORD width = (rect->right + 0xf) & ~0xf, height = (rect->bottom + 0xf) & ~0xf; + static const char magic[2] = "BM"; + struct + { + DWORD length; + DWORD reserved; + DWORD offset; + BITMAPINFOHEADER biHeader; + } header = + { + .length = length + sizeof(header) + 2, .offset = sizeof(header) + 2, + .biHeader = + { + .biSize = sizeof(BITMAPINFOHEADER), .biWidth = width, .biHeight = height, .biPlanes = 1, + .biBitCount = 32, .biCompression = BI_RGB, .biSizeImage = width * height * 4, + }, + }; + DWORD written; + BOOL ret; + + ret = WriteFile(output, magic, sizeof(magic), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(magic), "written %lu bytes\n", written); + ret = WriteFile(output, &header, sizeof(header), &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == sizeof(header), "written %lu bytes\n", written); + ret = WriteFile(output, data, length, &written, NULL); + ok(ret, "WriteFile failed, error %lu\n", GetLastError()); + ok(written == length, "written %lu bytes\n", written); +} + +#define check_rgb32_data(a, b, c, d, e) check_rgb32_data_(__LINE__, a, b, c, d, e) +static void check_rgb32_data_(int line, const WCHAR *filename, const BYTE *data, DWORD length, const RECT *rect, BOOL todo) +{ + WCHAR output_path[MAX_PATH]; + const BYTE *expect_data; + HRSRC resource; + HANDLE output; + DWORD diff; + + GetTempPathW(ARRAY_SIZE(output_path), output_path); + lstrcatW(output_path, filename); + output = CreateFileW(output_path, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + ok(output != INVALID_HANDLE_VALUE, "CreateFileW failed, error %lu\n", GetLastError()); + dump_rgb32(data, length, rect, output); + trace("created %s\n", debugstr_w(output_path)); + CloseHandle(output); + + resource = FindResourceW(NULL, filename, (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW failed, error %lu\n", GetLastError()); + expect_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + + diff = compare_rgb32(data, &length, rect, expect_data); + todo_wine_if(todo) + ok_(__FILE__, line)(diff == 0, "Unexpected %lu%% diff\n", diff); +} + static void init_functions(void) { - HMODULE mod = GetModuleHandleA("mfplat.dll"); + HMODULE mod;
#define X(f) p##f = (void*)GetProcAddress(mod, #f) - X(MFCreateDXGIDeviceManager); + if ((mod = GetModuleHandleA("mfplat.dll"))) + { + X(MFCreateDXGIDeviceManager); + } + + if ((mod = LoadLibraryA("d3d11.dll"))) + { + X(D3D11CreateDevice); + } #undef X }
@@ -138,6 +234,34 @@ static struct media_engine_notify *create_callback(void) return object; }
+static ID3D11Device *create_d3d11_device(void) +{ + static const D3D_FEATURE_LEVEL default_feature_level[] = + { + D3D_FEATURE_LEVEL_11_0, + D3D_FEATURE_LEVEL_10_1, + D3D_FEATURE_LEVEL_10_0, + }; + const D3D_FEATURE_LEVEL *feature_level; + unsigned int feature_level_count; + ID3D11Device *device; + + feature_level = default_feature_level; + feature_level_count = ARRAY_SIZE(default_feature_level); + + if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, + feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL))) + return device; + if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_WARP, NULL, 0, + feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL))) + return device; + if (SUCCEEDED(pD3D11CreateDevice(NULL, D3D_DRIVER_TYPE_REFERENCE, NULL, 0, + feature_level, feature_level_count, D3D11_SDK_VERSION, &device, NULL, NULL))) + return device; + + return NULL; +} + static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback, IUnknown *device, UINT32 output_format) { IMFDXGIDeviceManager *manager; @@ -152,6 +276,14 @@ static IMFMediaEngine *create_media_engine(IMFMediaEngineNotify *callback, IUnkn hr = MFCreateAttributes(&attributes, 3); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ if (device) + { + hr = IMFDXGIDeviceManager_ResetDevice(manager, device, token); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_DXGI_MANAGER, (IUnknown *)manager); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + } + hr = IMFAttributes_SetUnknown(attributes, &MF_MEDIA_ENGINE_CALLBACK, (IUnknown *)callback); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); hr = IMFAttributes_SetUINT32(attributes, &MF_MEDIA_ENGINE_VIDEO_OUTPUT_FORMAT, output_format); @@ -972,6 +1104,214 @@ static void test_audio_configuration(void) IMFMediaEngineNotify_Release(¬ify->IMFMediaEngineNotify_iface); }
+static IMFByteStream *load_resource(const WCHAR *name, const WCHAR *mime) +{ + IMFAttributes *attributes; + const BYTE *resource_data; + IMFByteStream *stream; + ULONG resource_len; + HRSRC resource; + HRESULT hr; + + resource = FindResourceW(NULL, name, (const WCHAR *)RT_RCDATA); + ok(resource != 0, "FindResourceW %s failed, error %lu\n", debugstr_w(name), GetLastError()); + resource_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource)); + resource_len = SizeofResource(GetModuleHandleW(NULL), resource); + + hr = MFCreateTempFile(MF_ACCESSMODE_READWRITE, MF_OPENMODE_DELETE_IF_EXIST, MF_FILEFLAGS_NONE, &stream); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_Write(stream, resource_data, resource_len, &resource_len); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFByteStream_SetCurrentPosition(stream, 0); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFByteStream_QueryInterface(stream, &IID_IMFAttributes, (void **)&attributes); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + hr = IMFAttributes_SetString(attributes, &MF_BYTESTREAM_CONTENT_TYPE, mime); + ok(hr == S_OK, "Failed to set string value, hr %#lx.\n", hr); + IMFAttributes_Release(attributes); + + return stream; +} + +struct test_transfer_notify +{ + IMFMediaEngineNotify IMFMediaEngineNotify_iface; + + IMFMediaEngineEx *media_engine; + HANDLE ready_event; + HRESULT error; +}; + +static HRESULT WINAPI test_transfer_notify_QueryInterface(IMFMediaEngineNotify *iface, REFIID riid, void **obj) +{ + if (IsEqualIID(riid, &IID_IUnknown) + || IsEqualIID(riid, &IID_IMFMediaEngineNotify)) + { + *obj = iface; + IMFMediaEngineNotify_AddRef(iface); + return S_OK; + } + + *obj = NULL; + return E_NOINTERFACE; +} + +static ULONG WINAPI test_transfer_notify_AddRef(IMFMediaEngineNotify *iface) +{ + return 2; +} + +static ULONG WINAPI test_transfer_notify_Release(IMFMediaEngineNotify *iface) +{ + return 1; +} + +static HRESULT WINAPI test_transfer_notify_EventNotify(IMFMediaEngineNotify *iface, DWORD event, DWORD_PTR param1, DWORD param2) +{ + struct test_transfer_notify *notify = CONTAINING_RECORD(iface, struct test_transfer_notify, IMFMediaEngineNotify_iface); + IMFMediaEngineEx *media_engine = notify->media_engine; + DWORD width, height; + HRESULT hr; + BOOL ret; + + switch (event) + { + case MF_MEDIA_ENGINE_EVENT_CANPLAY: + hr = IMFMediaEngineEx_Play(media_engine); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + break; + + case MF_MEDIA_ENGINE_EVENT_FORMATCHANGE: + ret = IMFMediaEngineEx_HasVideo(media_engine); + ok(ret, "Unexpected HasVideo %u.\n", ret); + hr = IMFMediaEngineEx_GetNativeVideoSize(media_engine, &width, &height); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(width == 64, "Unexpected width %lu.\n", width); + ok(height == 64, "Unexpected height %lu.\n", height); + break; + + case MF_MEDIA_ENGINE_EVENT_ERROR: + ok(broken(param2 == MF_E_UNSUPPORTED_BYTESTREAM_TYPE), "Unexpected error %#lx\n", param2); + notify->error = param2; + /* fallthrough */ + case MF_MEDIA_ENGINE_EVENT_FIRSTFRAMEREADY: + case MF_MEDIA_ENGINE_EVENT_TIMEUPDATE: + SetEvent(notify->ready_event); + break; + } + + return S_OK; +} + +static IMFMediaEngineNotifyVtbl test_transfer_notify_vtbl = +{ + test_transfer_notify_QueryInterface, + test_transfer_notify_AddRef, + test_transfer_notify_Release, + test_transfer_notify_EventNotify, +}; + +static void test_TransferVideoFrames(void) +{ + struct test_transfer_notify notify = {{&test_transfer_notify_vtbl}}; + ID3D11Texture2D *texture, *rb_texture; + D3D11_MAPPED_SUBRESOURCE map_desc; + IMFMediaEngineEx *media_engine; + ID3D11DeviceContext *context; + WCHAR url[] = {L"test.mp4"}; + D3D11_TEXTURE2D_DESC desc; + IMFByteStream *stream; + ID3D11Device *device; + RECT dst_rect; + HRESULT hr; + DWORD res; + + stream = load_resource(L"test.mp4", L"video/mp4"); + + notify.ready_event = CreateEventW(NULL, FALSE, FALSE, NULL); + ok(!!notify.ready_event, "CreateEventW failed, error %lu\n", GetLastError()); + + if (!(device = create_d3d11_device())) + { + skip("Failed to create a D3D11 device, skipping tests.\n"); + return; + } + + if (!(media_engine = create_media_engine_ex(¬ify.IMFMediaEngineNotify_iface, + (IUnknown *)device, DXGI_FORMAT_B8G8R8X8_UNORM))) + return; + notify.media_engine = media_engine; + + memset(&desc, 0, sizeof(desc)); + desc.Width = 64; + desc.Height = 64; + desc.ArraySize = 1; + desc.Format = DXGI_FORMAT_B8G8R8X8_UNORM; + desc.BindFlags = D3D11_BIND_RENDER_TARGET; + desc.SampleDesc.Count = 1; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &texture); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + hr = IMFMediaEngineEx_SetSourceFromByteStream(media_engine, stream, url); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + IMFByteStream_Release(stream); + + res = WaitForSingleObject(notify.ready_event, 5000); + ok(!res, "Unexpected res %#lx.\n", res); + + if (FAILED(notify.error)) + { + win_skip("Media engine reported error %#lx, skipping tests.\n", notify.error); + goto done; + } + + /* FIXME: Wine first video frame is often full of garbage, wait for another update */ + res = WaitForSingleObject(notify.ready_event, 500); + /* It's also missing the MF_MEDIA_ENGINE_EVENT_TIMEUPDATE notifications */ + todo_wine + ok(!res, "Unexpected res %#lx.\n", res); + + SetRect(&dst_rect, 0, 0, desc.Width, desc.Height); + hr = IMFMediaEngineEx_TransferVideoFrame(notify.media_engine, (IUnknown *)texture, NULL, NULL, NULL); + ok(hr == S_OK || broken(hr == E_POINTER) /* w1064v1507 */, "Unexpected hr %#lx.\n", hr); + if (hr == E_POINTER) + goto done; + + ID3D11Texture2D_GetDesc(texture, &desc); + desc.Usage = D3D11_USAGE_STAGING; + desc.BindFlags = 0; + desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ; + desc.MiscFlags = 0; + hr = ID3D11Device_CreateTexture2D(device, &desc, NULL, &rb_texture); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + ID3D11Device_GetImmediateContext(device, &context); + ID3D11DeviceContext_CopySubresourceRegion(context, (ID3D11Resource *)rb_texture, + 0, 0, 0, 0, (ID3D11Resource *)texture, 0, NULL); + + memset(&map_desc, 0, sizeof(map_desc)); + hr = ID3D11DeviceContext_Map(context, (ID3D11Resource *)rb_texture, 0, D3D11_MAP_READ, 0, &map_desc); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + ok(!!map_desc.pData, "got pData %p\n", map_desc.pData); + ok(map_desc.DepthPitch == 16384, "got DepthPitch %u\n", map_desc.DepthPitch); + ok(map_desc.RowPitch == desc.Width * 4, "got RowPitch %u\n", map_desc.RowPitch); + check_rgb32_data(L"rgb32frame.bmp", map_desc.pData, map_desc.RowPitch * desc.Height, &dst_rect, TRUE); + ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)rb_texture, 0); + + ID3D11DeviceContext_Release(context); + ID3D11Texture2D_Release(rb_texture); + +done: + IMFMediaEngineEx_Shutdown(media_engine); + IMFMediaEngineEx_Release(media_engine); + + ID3D11Texture2D_Release(texture); + ID3D11Device_Release(device); + + CloseHandle(notify.ready_event); +} + START_TEST(mfmediaengine) { HRESULT hr; @@ -1002,6 +1342,7 @@ START_TEST(mfmediaengine) test_time_range(); test_SetSourceFromByteStream(); test_audio_configuration(); + test_TransferVideoFrames();
IMFMediaEngineClassFactory_Release(factory);
diff --git a/dlls/mfmediaengine/tests/resource.rc b/dlls/mfmediaengine/tests/resource.rc new file mode 100644 index 00000000000..0f9f1678495 --- /dev/null +++ b/dlls/mfmediaengine/tests/resource.rc @@ -0,0 +1,32 @@ +/* + * Copyright 2022 Rémi Bernon 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" + +/* Generated with: + * gst-launch-1.0 videotestsrc num-buffers=60 pattern=smpte100 ! \ + * video/x-raw,format=I420,width=64,height=64,framerate=30000/1001 ! \ + * videoflip method=clockwise ! videoconvert ! \ + * x264enc ! mp4mux ! filesink location=dlls/mfmediaengine/tests/test.mp4 + */ +/* @makedep: test.mp4 */ +test.mp4 RCDATA test.mp4 + +/* Generated from running the tests on Windows */ +/* @makedep: rgb32frame.bmp */ +rgb32frame.bmp RCDATA rgb32frame.bmp diff --git a/dlls/mfmediaengine/tests/rgb32frame.bmp b/dlls/mfmediaengine/tests/rgb32frame.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b8ca716abb5b4dccd0a2ba61a8392b106721b0e2 GIT binary patch literal 16438 zcmeI$!4ZNm5CzcCfVSY#3OF;~?M3ZFX%!n_T~J4D!F`$efopyqgyC@PhqjJB=Y3{) zrE9yq%Q39;&lH9RG@t<uXg~wy8o1?(E9X2-Q8_L5Uv$6#0}L?0KrI8cR!g`2W`F?( z7+_#AFvhlYF83Cd)1?8?0Rs#$zyJfa49xi%EIMF-0R|Xgpq7E_CZcjqZHmfiZH}7B xzn}T-TXXHpo?E~D=il@1{a@3-^ZoyI5WEir*U#ao3tce400Rs#z`)-bcmN3t5E=jg
literal 0 HcmV?d00001
diff --git a/dlls/mfmediaengine/tests/test.mp4 b/dlls/mfmediaengine/tests/test.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..752d860008d472a1bfb26a1a97ef0c9b36ab2ba5 GIT binary patch literal 3983 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 JJHR;<_)p|_beRAE
literal 0 HcmV?d00001
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mfmediaengine/main.c | 38 +++++++++++------------- dlls/mfmediaengine/tests/mfmediaengine.c | 7 ++--- 2 files changed, 21 insertions(+), 24 deletions(-)
diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c index a191448b69f..b2ddc376db8 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -284,38 +284,36 @@ static HRESULT media_engine_create_d3d11_video_frame_resources(struct media_engi if (position.x < dst.x || position.x > dst.z) return backcolor; if (position.y < dst.y || position.y > dst.w) return backcolor; p.x = (position.x - dst.x) / (dst.z - dst.x); - p.y = 1.0f - (position.y - dst.y) / (dst.w - dst.y); + p.y = (position.y - dst.y) / (dst.w - dst.y); p.x = src.x + p.x * (src.z - src.x); p.y = src.y + p.y * (src.w - src.y); return t.Sample(s, p); } #endif - 0x43425844, 0x5892e3b1, 0x24c17f7c, 0x9999f143, 0x49667872, 0x00000001, 0x0000032c, 0x00000003, + 0x43425844, 0xae2162b7, 0x0fd69625, 0x6784c41a, 0x84ae95de, 0x00000001, 0x000002f8, 0x00000003, 0x0000002c, 0x00000060, 0x00000094, 0x4e475349, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000001, 0x00000003, 0x00000000, 0x0000030f, 0x505f5653, 0x5449534f, 0x004e4f49, 0x4e47534f, 0x0000002c, 0x00000001, 0x00000008, 0x00000020, 0x00000000, 0x00000000, 0x00000003, - 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x00000290, 0x00000040, - 0x000000a4, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x0300005a, 0x00106000, 0x00000000, + 0x00000000, 0x0000000f, 0x545f5653, 0x45475241, 0xabab0054, 0x52444853, 0x0000025c, 0x00000040, + 0x00000097, 0x04000059, 0x00208e46, 0x00000000, 0x00000003, 0x0300005a, 0x00106000, 0x00000000, 0x04001858, 0x00107000, 0x00000000, 0x00005555, 0x04002064, 0x00101032, 0x00000000, 0x00000001, 0x03000065, 0x001020f2, 0x00000000, 0x02000068, 0x00000002, 0x08000031, 0x00100012, 0x00000000, 0x0010100a, 0x00000000, 0x0020800a, 0x00000000, 0x00000000, 0x08000031, 0x00100022, 0x00000000, 0x0020802a, 0x00000000, 0x00000000, 0x0010100a, 0x00000000, 0x0700003c, 0x00100012, 0x00000000, - 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x06000036, - 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000002, 0x0100003e, 0x01000015, 0x08000031, - 0x00100012, 0x00000000, 0x0010101a, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x08000031, - 0x00100022, 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x0010101a, 0x00000000, 0x0700003c, - 0x00100012, 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, - 0x00000000, 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000002, 0x0100003e, - 0x01000015, 0x09000000, 0x00100032, 0x00000000, 0x00101046, 0x00000000, 0x80208046, 0x00000041, - 0x00000000, 0x00000000, 0x0a000000, 0x001000c2, 0x00000000, 0x80208406, 0x00000041, 0x00000000, - 0x00000000, 0x00208ea6, 0x00000000, 0x00000000, 0x0700000e, 0x00100032, 0x00000000, 0x00100046, - 0x00000000, 0x00100ae6, 0x00000000, 0x08000000, 0x00100022, 0x00000000, 0x8010001a, 0x00000041, - 0x00000000, 0x00004001, 0x3f800000, 0x0a000000, 0x001000c2, 0x00000000, 0x80208406, 0x00000041, - 0x00000000, 0x00000001, 0x00208ea6, 0x00000000, 0x00000001, 0x0a000032, 0x00100012, 0x00000001, - 0x0010000a, 0x00000000, 0x0010002a, 0x00000000, 0x0020800a, 0x00000000, 0x00000001, 0x0a000032, - 0x00100022, 0x00000001, 0x0010001a, 0x00000000, 0x0010003a, 0x00000000, 0x0020801a, 0x00000000, - 0x00000001, 0x09000045, 0x001020f2, 0x00000000, 0x00100046, 0x00000001, 0x00107e46, 0x00000000, - 0x00106000, 0x00000000, 0x0100003e, + 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x09000000, 0x00100062, 0x00000000, 0x00101106, + 0x00000000, 0x80208106, 0x00000041, 0x00000000, 0x00000000, 0x0a000000, 0x00100032, 0x00000001, + 0x80208046, 0x00000041, 0x00000000, 0x00000000, 0x00208ae6, 0x00000000, 0x00000000, 0x0700000e, + 0x00100062, 0x00000000, 0x00100656, 0x00000000, 0x00100106, 0x00000001, 0x0a000000, 0x00100032, + 0x00000001, 0x80208046, 0x00000041, 0x00000000, 0x00000001, 0x00208ae6, 0x00000000, 0x00000001, + 0x0a000032, 0x00100062, 0x00000000, 0x00100656, 0x00000000, 0x00100106, 0x00000001, 0x00208106, + 0x00000000, 0x00000001, 0x09000045, 0x001000f2, 0x00000001, 0x00100596, 0x00000000, 0x00107e46, + 0x00000000, 0x00106000, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, 0x06000036, 0x001020f2, + 0x00000000, 0x00208e46, 0x00000000, 0x00000002, 0x0100003e, 0x01000015, 0x08000031, 0x00100012, + 0x00000000, 0x0010101a, 0x00000000, 0x0020801a, 0x00000000, 0x00000000, 0x08000031, 0x00100022, + 0x00000000, 0x0020803a, 0x00000000, 0x00000000, 0x0010101a, 0x00000000, 0x0700003c, 0x00100012, + 0x00000000, 0x0010001a, 0x00000000, 0x0010000a, 0x00000000, 0x0304001f, 0x0010000a, 0x00000000, + 0x06000036, 0x001020f2, 0x00000000, 0x00208e46, 0x00000000, 0x00000002, 0x0100003e, 0x01000015, + 0x05000036, 0x001020f2, 0x00000000, 0x00100e46, 0x00000001, 0x0100003e, }; D3D11_SUBRESOURCE_DATA resource_data; D3D11_TEXTURE2D_DESC texture_desc; diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c index 1b1f60742af..69f5d8ab93b 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c @@ -124,8 +124,8 @@ static void dump_rgb32(const BYTE *data, DWORD length, const RECT *rect, HANDLE ok(written == length, "written %lu bytes\n", written); }
-#define check_rgb32_data(a, b, c, d, e) check_rgb32_data_(__LINE__, a, b, c, d, e) -static void check_rgb32_data_(int line, const WCHAR *filename, const BYTE *data, DWORD length, const RECT *rect, BOOL todo) +#define check_rgb32_data(a, b, c, d) check_rgb32_data_(__LINE__, a, b, c, d) +static void check_rgb32_data_(int line, const WCHAR *filename, const BYTE *data, DWORD length, const RECT *rect) { WCHAR output_path[MAX_PATH]; const BYTE *expect_data; @@ -146,7 +146,6 @@ static void check_rgb32_data_(int line, const WCHAR *filename, const BYTE *data, expect_data = LockResource(LoadResource(GetModuleHandleW(NULL), resource));
diff = compare_rgb32(data, &length, rect, expect_data); - todo_wine_if(todo) ok_(__FILE__, line)(diff == 0, "Unexpected %lu%% diff\n", diff); }
@@ -1296,7 +1295,7 @@ static void test_TransferVideoFrames(void) ok(!!map_desc.pData, "got pData %p\n", map_desc.pData); ok(map_desc.DepthPitch == 16384, "got DepthPitch %u\n", map_desc.DepthPitch); ok(map_desc.RowPitch == desc.Width * 4, "got RowPitch %u\n", map_desc.RowPitch); - check_rgb32_data(L"rgb32frame.bmp", map_desc.pData, map_desc.RowPitch * desc.Height, &dst_rect, TRUE); + check_rgb32_data(L"rgb32frame.bmp", map_desc.pData, map_desc.RowPitch * desc.Height, &dst_rect); ID3D11DeviceContext_Unmap(context, (ID3D11Resource *)rb_texture, 0);
ID3D11DeviceContext_Release(context);
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=124914
Your paranoid android.
=== debian11 (build log) ===
Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24703. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24703. Use of uninitialized value $Flaky in addition (+) at /home/testbot/lib/WineTestBot/LogUtils.pm line 720, <$LogFile> line 24703.
For some reason I get this, only on 64-bit:
mfmediaengine.c:1298: Test failed: Unexpected 3% diff
On Wed Oct 12 17:12:10 2022 +0000, Nikolay Sivov wrote:
For some reason I get this, only on 64-bit: mfmediaengine.c:1298: Test failed: Unexpected 3% diff
Hmm, maybe some small differences related to how video gets decoded? Sometimes the colors are bleeding a bit. If the generated bmp look okay, I can raise a bit the threshold.
We could probably feed it raw video with minimal frame size? So this difference never appears. Could it be that Transfer() function behaves differently because of a shader?