This shows that media session samples are correctly oriented, but that mfmediaengine renders them upside down.
-- v2: 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 | 238 ++++++++++++++++++++++++++- dlls/mf/tests/mf_test.h | 37 +++++ 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 | 43 +---- 7 files changed, 300 insertions(+), 35 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..62a9f3abaed 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1879,6 +1879,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 +2592,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 +2630,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 +2676,29 @@ 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); + hr = IMFSample_SetSampleTime(sample, sample_time); + 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 +2724,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 +4619,159 @@ 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_time = 1334668, .sample_duration = 333667, .todo_time = 667334, + .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_time = 1334668, .sample_duration = 333667, .todo_time = 667334, + .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 +6473,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..4bbfa7170f0 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -57,3 +57,40 @@ typedef struct attribute_desc media_type_desc[32]; #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); extern void init_media_type(IMFMediaType *mediatype, const struct attribute_desc *desc, ULONG limit); +extern IMFSample *create_sample(const BYTE *data, ULONG size); + +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_(__LINE__, a, b, c) +extern DWORD check_mf_sample_collection_(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..f7eeadef376 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -367,9 +367,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 +401,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 +434,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 +459,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 +480,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 +513,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 +535,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 +557,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) @@ -790,7 +765,7 @@ static void check_mf_sample_collection_enum(IMFSample *sample, const struct samp }
#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_(int line, IMFCollection *samples, const struct sample_desc *expect_samples, const WCHAR *expect_data_filename) { struct check_mf_sample_context ctx = {.line = line}; @@ -1328,7 +1303,7 @@ static void test_sample_copier_output_processing(void) ok(ref == 0, "Release returned %ld\n", ref); }
-static IMFSample *create_sample(const BYTE *data, ULONG size) +IMFSample *create_sample(const BYTE *data, ULONG size) { IMFMediaBuffer *media_buffer; IMFSample *sample;
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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=124222
Your paranoid android.
=== w7u_2qxl (32 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== w7u_adm (32 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== w7u_el (32 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== w1064v1507 (32 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== w1064v1809 (32 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== w1064v1507 (64 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== w1064v1809 (64 bit report) ===
mf: transform.c:4732: Test failed: sample 0: got sample time 667334 transform.c:4745: Test failed: sample 0: got sample time 667334
Report validation errors: mf:mf contains a misplaced failure line for transform
=== debian11 (32 bit report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit ar:MA report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit de report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit fr report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit he:IL report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit hi:IN report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit ja:JP report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit zh:CN report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit WoW report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (64 bit WoW report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
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: ; }
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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=124223
Your paranoid android.
=== debian11 (32 bit report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit zh:CN report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (32 bit WoW report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
=== debian11 (64 bit WoW report) ===
Report validation errors: mf:mf contains a misplaced todo line for transform
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 | 344 ++++++++++++++++++++++- 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, 376 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..60a914a6020 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,213 @@ 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); + + 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); + + SetRect(&dst_rect, 0, 0, desc.Width, desc.Height); + hr = IMFMediaEngineEx_TransferVideoFrame(notify.media_engine, (IUnknown *)texture, NULL, NULL, NULL); + ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); + + 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 +1341,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
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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=124225
Your paranoid android.
=== w1064v1507 (32 bit report) ===
mfmediaengine: mfmediaengine.c:1287: Test failed: Unexpected hr 0x80004003. mfmediaengine.c:1298: Test failed: Unexpected 56% diff
=== w1064v1507 (64 bit report) ===
mfmediaengine: mfmediaengine.c:1287: Test failed: Unexpected hr 0x80004003. mfmediaengine.c:1298: Test failed: Unexpected 56% diff
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 60a914a6020..ee2f49710c5 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); }
@@ -1295,7 +1294,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 full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=124226
Your paranoid android.
=== w1064v1507 (32 bit report) ===
mfmediaengine: mfmediaengine.c:1286: Test failed: Unexpected hr 0x80004003. mfmediaengine.c:1297: Test failed: Unexpected 56% diff
=== w1064v1507 (64 bit report) ===
mfmediaengine: mfmediaengine.c:1286: Test failed: Unexpected hr 0x80004003. mfmediaengine.c:1297: Test failed: Unexpected 56% diff