This shows that media session samples are correctly oriented, but that mfmediaengine renders them upside down.
-- v3: 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: Avoid clearing media session command list while it is running. 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 43493319046..2c846c32de5 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -58,6 +58,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 @@ -69,3 +73,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 9b30b9cafda..c78370db44f 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -84,7 +84,8 @@ static void check_interface_(unsigned int line, void *iface_ptr, REFIID iid, BOO IUnknown_Release(unk); }
-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; @@ -95,7 +96,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) @@ -122,7 +123,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); } } @@ -367,9 +368,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;
@@ -403,7 +402,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;
@@ -436,7 +435,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;
@@ -461,7 +460,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; @@ -482,9 +481,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"; @@ -517,7 +514,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; @@ -539,7 +536,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; @@ -561,27 +558,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) @@ -682,8 +658,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; @@ -691,20 +667,20 @@ static DWORD check_mf_media_buffer_(int line, IMFMediaBuffer *buffer, const stru BYTE *data;
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); @@ -718,63 +694,64 @@ struct check_mf_sample_context const BYTE *data; DWORD data_len; DWORD diff; + const char *file; int line; };
static void check_mf_sample_buffer(IMFMediaBuffer *buffer, const struct buffer_desc *expect, void *context) { struct check_mf_sample_context *ctx = context; - 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 = *expect_data + min(total_length, *expect_data_len); @@ -786,14 +763,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;
@@ -803,7 +779,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
This fixes a random crash with mfmediaengine tests, which quickly starts then shuts down a media session. --- dlls/mf/session.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/mf/session.c b/dlls/mf/session.c index 8be3ffcd7f3..b410a5fe861 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -47,6 +47,7 @@ enum session_command SESSION_CMD_PAUSE, SESSION_CMD_STOP, SESSION_CMD_SET_RATE, + SESSION_CMD_SHUTDOWN, };
struct session_op @@ -460,7 +461,10 @@ static HRESULT session_submit_command(struct media_session *session, struct sess { if (list_empty(&session->commands) && !(session->presentation.flags & SESSION_FLAG_PENDING_COMMAND)) hr = MFPutWorkItem(MFASYNC_CALLBACK_QUEUE_STANDARD, &session->commands_callback, &op->IUnknown_iface); - list_add_tail(&session->commands, &op->entry); + if (op->command == SESSION_CMD_SHUTDOWN) + list_add_head(&session->commands, &op->entry); + else + list_add_tail(&session->commands, &op->entry); IUnknown_AddRef(&op->IUnknown_iface); } LeaveCriticalSection(&session->cs); @@ -2041,7 +2045,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) IMFPresentationClock_Release(session->clock); session->clock = NULL; session_clear_presentation(session); - session_clear_command_list(session); + session_submit_simple_command(session, SESSION_CMD_SHUTDOWN); } LeaveCriticalSection(&session->cs);
@@ -2383,6 +2387,10 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, case SESSION_CMD_SET_RATE: session_set_rate(session, op->set_rate.thin, op->set_rate.rate); break; + case SESSION_CMD_SHUTDOWN: + session_clear_command_list(session); + session_command_complete(session); + break; default: ; }
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);
v3: Fix the test failures: add a file parameter to helpers, drop the inconsistent check for sample grabber sample time, add a broken result for mfmediaengine on w1064v1507.
I'll rebase the MR later, I think there's some small conflicts with https://gitlab.winehq.org/wine/wine/-/merge_requests/972 and I split the session change to https://gitlab.winehq.org/wine/wine/-/merge_requests/973.