This tests that the resolution should be quick enough to not trigger an Unreal Engine race condition. This also checks the determinism of the media source presentation descriptor stream ordering, as well as the stream selection updates when the media source is started.
From: Rémi Bernon rbernon@codeweavers.com
Unreal Engine has a race condition in its media player where it starts the resolution of a media source, waiting for its completion in an async task, and expects to set the media player source from its result.
At the same time, the media player uses timer to tick every 200ms or so, and if the first tick happens before the media source resolution end, the media player ends up in a corrupted state and playback may fail or get stuck.
On Windows, the media source resolution takes very little time, and usually less than 1ms. On Wine, because of the current design of the media soruce, it can often take more than 200ms depending on the setup, and very rarely less than 50ms. --- dlls/mf/tests/mf.c | 120 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 120 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index e8d7252aa3f..5fd8adb2f6b 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -41,6 +41,9 @@ #include "initguid.h" #include "evr9.h"
+DEFINE_GUID(CLSID_MPEG4ByteStreamHandler,0x271c3902,0x6095,0x4c45,0xa2,0x2f,0x20,0x09,0x18,0x16,0xee,0x9e); +DEFINE_GUID(CLSID_GStreamerByteStreamHandler,0x317df618,0x5e5a,0x468a,0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62); + #define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE
@@ -1815,6 +1818,7 @@ struct test_callback LONG refcount;
HANDLE event; + IMFAsyncResult *result; IMFMediaEvent *media_event; BOOL check_media_event; }; @@ -1851,6 +1855,8 @@ static ULONG WINAPI testcallback_Release(IMFAsyncCallback *iface)
if (!refcount) { + if (callback->result) + IMFAsyncResult_Release(callback->result); if (callback->media_event) IMFMediaEvent_Release(callback->media_event); CloseHandle(callback->event); @@ -1890,6 +1896,7 @@ static HRESULT WINAPI testcallback_Invoke(IMFAsyncCallback *iface, IMFAsyncResul IUnknown_Release(object); }
+ IMFAsyncResult_AddRef((callback->result = result)); SetEvent(callback->event);
return S_OK; @@ -1920,6 +1927,18 @@ static IMFAsyncCallback *create_test_callback(BOOL check_media_event) return &callback->IMFAsyncCallback_iface; }
+static void wait_async_result(IMFAsyncCallback *iface, IMFAsyncResult **result) +{ + struct test_callback *impl = impl_from_IMFAsyncCallback(iface); + UINT ret; + + ret = WaitForSingleObject(impl->event, 5000); + ok(!ret, "WaitForSingleObject returned %#x\n", ret); + + if ((*result = impl->result)) + impl->result = NULL; +} + #define wait_media_event(a, b, c, d, e) wait_media_event_(__LINE__, a, b, c, d, e) static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCallback *callback, MediaEventType expect_type, DWORD timeout, PROPVARIANT *value) @@ -6704,6 +6723,106 @@ static void test_MFRequireProtectedEnvironment(void) ok(ref == 0, "Release returned %ld\n", ref); }
+static void load_resource_stream(const WCHAR *name, IMFByteStream **stream) +{ + HRSRC resource = FindResourceW(NULL, name, (const WCHAR *)RT_RCDATA); + void *resource_data; + DWORD resource_len; + HRESULT hr; + + 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); +} + +static void subtest_media_source(const WCHAR *resource, const GUID *guid) +{ + IMFByteStreamHandler *handler; + IMFAsyncCallback *callback; + IMFAsyncResult *result; + IMFByteStream *stream; + IUnknown *tmp_unknown; + MF_OBJECT_TYPE type; + DWORD time = 0; + QWORD bytes; + HRESULT hr; + + if (!strcmp(winetest_platform, "wine")) guid = &CLSID_GStreamerByteStreamHandler; + + hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); + ok(hr == S_OK, "got hr %#lx\n", hr); + + callback = create_test_callback(FALSE); + ok(!!callback, "got callback %p\n", callback); + + hr = CoCreateInstance(guid, NULL, CLSCTX_INPROC_SERVER, &IID_IMFByteStreamHandler, (void **)&handler); + ok(hr == S_OK, "got hr %#lx\n", hr); + + check_interface(handler, &IID_IUnknown, TRUE); + check_interface(handler, &IID_IMFAsyncCallback, FALSE); + + hr = IMFByteStreamHandler_GetMaxNumberOfBytesRequiredForResolution(handler, &bytes); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + + + load_resource_stream(resource, &stream); + + time -= GetTickCount(); + hr = IMFByteStreamHandler_BeginCreateObject(handler, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, NULL, callback, NULL); + ok(hr == S_OK, "got hr %#lx\n", hr); + wait_async_result(callback, &result); + time += GetTickCount(); + todo_wine ok(time <= 5 || broken(time <= 20) /* testbot may be very slow */, "source resolution took %lums\n", time); + ok(!!result, "got result %p\n", result); + + IMFByteStream_Release(stream); + + + hr = IMFAsyncResult_GetStatus(result); + if (hr == MF_E_CANNOT_PARSE_BYTESTREAM) + { + hr = IMFByteStreamHandler_EndCreateObject(handler, result, &type, &tmp_unknown); + ok(hr == MF_E_CANNOT_PARSE_BYTESTREAM, "got hr %#lx\n", hr); + IMFAsyncResult_Release(result); + + win_skip("MP4 media source is not supported, skipping tests.\n"); + goto skip_tests; + } + + ok(hr == S_OK, "got hr %#lx\n", hr); + hr = IMFAsyncResult_GetObject(result, &tmp_unknown); + todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(tmp_unknown == (void *)handler, "got object %p\n", tmp_unknown); + if (handler == (void *)tmp_unknown) IUnknown_Release(tmp_unknown); + hr = IMFAsyncResult_GetState(result, &tmp_unknown); + ok(hr == E_POINTER, "got hr %#lx\n", hr); + + hr = IMFByteStreamHandler_EndCreateObject(handler, result, &type, &tmp_unknown); + ok(hr == S_OK, "got hr %#lx\n", hr); + IMFAsyncResult_Release(result); + + IUnknown_Release(tmp_unknown); + +skip_tests: + IMFByteStreamHandler_Release(handler); + IMFAsyncCallback_Release(callback); + + hr = MFShutdown(); + ok(hr == S_OK, "got hr %#lx\n", hr); +} + +static void test_media_source(void) +{ + subtest_media_source(L"test.mp4", &CLSID_MPEG4ByteStreamHandler); +} + START_TEST(mf) { init_functions(); @@ -6737,4 +6856,5 @@ START_TEST(mf) test_MFGetSupportedSchemes(); test_MFGetTopoNodeCurrentType(); test_MFRequireProtectedEnvironment(); + test_media_source(); }
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 81 +++++++++++++++++++++++++++-- dlls/mf/tests/mf_test.h | 1 + dlls/mf/tests/multiple-streams.avi | Bin 0 -> 47250 bytes dlls/mf/tests/multiple-streams.mp4 | Bin 0 -> 33041 bytes dlls/mf/tests/resource.rc | 53 +++++++++++++++++++ dlls/mf/tests/transform.c | 1 + 6 files changed, 133 insertions(+), 3 deletions(-) create mode 100644 dlls/mf/tests/multiple-streams.avi create mode 100644 dlls/mf/tests/multiple-streams.mp4
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 5fd8adb2f6b..2ff157e65d8 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -42,7 +42,9 @@ #include "evr9.h"
DEFINE_GUID(CLSID_MPEG4ByteStreamHandler,0x271c3902,0x6095,0x4c45,0xa2,0x2f,0x20,0x09,0x18,0x16,0xee,0x9e); +DEFINE_GUID(CLSID_AVIByteStreamHandler,0x7afa253e,0xf823,0x42f6,0xa5,0xd9,0x71,0x4b,0xde,0x46,0x74,0x12); DEFINE_GUID(CLSID_GStreamerByteStreamHandler,0x317df618,0x5e5a,0x468a,0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62); +static BOOL has_mp4_media_source;
#define DEFINE_EXPECT(func) \ static BOOL expect_ ## func = FALSE, called_ ## func = FALSE @@ -4922,6 +4924,7 @@ static void test_sample_grabber_orientation(GUID subtype) win_skip("MP4 media source is not supported, skipping tests.\n"); return; } + has_mp4_media_source = TRUE;
callback = create_test_callback(TRUE); grabber_callback = impl_from_IMFSampleGrabberSinkCallback(create_test_grabber_callback()); @@ -6723,6 +6726,13 @@ static void test_MFRequireProtectedEnvironment(void) ok(ref == 0, "Release returned %ld\n", ref); }
+struct presentation_desc +{ + UINT max_required_bytes; + UINT stream_count; + struct attribute_desc attributes[16]; +}; + static void load_resource_stream(const WCHAR *name, IMFByteStream **stream) { HRSRC resource = FindResourceW(NULL, name, (const WCHAR *)RT_RCDATA); @@ -6742,18 +6752,22 @@ static void load_resource_stream(const WCHAR *name, IMFByteStream **stream) ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); }
-static void subtest_media_source(const WCHAR *resource, const GUID *guid) +static void subtest_media_source(const WCHAR *resource, const GUID *guid, const struct presentation_desc *expect) { + IMFPresentationDescriptor *presentation; IMFByteStreamHandler *handler; + IMFMediaSource *media_source; IMFAsyncCallback *callback; IMFAsyncResult *result; IMFByteStream *stream; IUnknown *tmp_unknown; MF_OBJECT_TYPE type; - DWORD time = 0; + DWORD time = 0, stream_count; QWORD bytes; HRESULT hr;
+ winetest_push_context("%s", debugstr_w(resource)); + if (!strcmp(winetest_platform, "wine")) guid = &CLSID_GStreamerByteStreamHandler;
hr = MFStartup(MF_VERSION, MFSTARTUP_FULL); @@ -6770,6 +6784,7 @@ static void subtest_media_source(const WCHAR *resource, const GUID *guid)
hr = IMFByteStreamHandler_GetMaxNumberOfBytesRequiredForResolution(handler, &bytes); todo_wine ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(bytes == expect->max_required_bytes, "got bytes %I64u\n", bytes);
load_resource_stream(resource, &stream); @@ -6808,19 +6823,79 @@ static void subtest_media_source(const WCHAR *resource, const GUID *guid) ok(hr == S_OK, "got hr %#lx\n", hr); IMFAsyncResult_Release(result);
+ + check_interface(tmp_unknown, &IID_IMFMediaSource, TRUE); + todo_wine check_interface(tmp_unknown, &IID_IMFMediaSourceEx, has_mp4_media_source && has_video_processor /* >= w10 */); + check_interface(tmp_unknown, &IID_IMFMediaEventGenerator, TRUE); + check_interface(tmp_unknown, &IID_IMFGetService, TRUE); + + check_service_interface(tmp_unknown, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE); + check_service_interface(tmp_unknown, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE); + /* check_service_interface(tmp_unknown, &MF_QUALITY_SERVICES, &IID_IMFQualityAdvise, TRUE); */ + /* check_service_interface(tmp_unknown, &MF_METADATA_PROVIDER_SERVICE, &IID_IMFMetadataProvider, TRUE); */ + + hr = IUnknown_QueryInterface(tmp_unknown, &IID_IMFMediaSource, (void **)&media_source); + ok(hr == S_OK, "got hr %#lx\n", hr); IUnknown_Release(tmp_unknown);
+ + hr = IMFMediaSource_CreatePresentationDescriptor(media_source, &presentation); + ok(hr == S_OK, "got hr %#lx\n", hr); + + hr = IMFPresentationDescriptor_GetStreamDescriptorCount(presentation, &stream_count); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine_if(stream_count == 4 && expect->stream_count == 5) + ok(stream_count == expect->stream_count, "got stream_count %lu\n", stream_count); + check_attributes((IMFAttributes *)presentation, expect->attributes, -1); + IMFPresentationDescriptor_Release(presentation); + + hr = IMFMediaSource_Shutdown(media_source); + ok(hr == S_OK, "got hr %#lx\n", hr); + IMFMediaSource_Release(media_source); + + skip_tests: IMFByteStreamHandler_Release(handler); IMFAsyncCallback_Release(callback);
hr = MFShutdown(); ok(hr == S_OK, "got hr %#lx\n", hr); + + winetest_pop_context(); }
static void test_media_source(void) { - subtest_media_source(L"test.mp4", &CLSID_MPEG4ByteStreamHandler); +/* w7 doesn't have MF_PD_MIME_TYPE */ +#define ATTR_WSTR_OR_NONE(k, v, ...) {.key = has_video_processor ? &k : NULL, .name = #k, {.vt = VT_LPWSTR, .pwszVal = (WCHAR *)v}, __VA_ARGS__ } + const struct presentation_desc mp4_desc = + { + .max_required_bytes = has_video_processor ? 1024 : 16 /* w7 */, + .stream_count = 5, + .attributes = + { + ATTR_RATIO(MF_PD_DURATION, 0, 25000000), + ATTR_RATIO(MF_PD_TOTAL_FILE_SIZE, 0, 33041, .todo = TRUE), + ATTR_WSTR_OR_NONE(MF_PD_MIME_TYPE, L"video/mp4", .todo = TRUE), + }, + }; + const struct presentation_desc avi_desc = + { + .max_required_bytes = 12, + .stream_count = 3, + .attributes = + { + ATTR_RATIO(MF_PD_DURATION, 0, 20020000), + ATTR_RATIO(MF_PD_TOTAL_FILE_SIZE, 0, 47250, .todo = TRUE), + ATTR_UINT32(MF_PD_AUDIO_ENCODING_BITRATE, 106176, .todo = TRUE), + ATTR_UINT32(MF_PD_VIDEO_ENCODING_BITRATE, 1125200, .todo = TRUE), + ATTR_WSTR_OR_NONE(MF_PD_MIME_TYPE, L"video/avi", .todo = TRUE), + }, + }; +#undef ATTR_WSTR_OR_NONE + + subtest_media_source(L"multiple-streams.mp4", &CLSID_MPEG4ByteStreamHandler, &mp4_desc); + subtest_media_source(L"multiple-streams.avi", &CLSID_AVIByteStreamHandler, &avi_desc); }
START_TEST(mf) diff --git a/dlls/mf/tests/mf_test.h b/dlls/mf/tests/mf_test.h index 77af51abd55..7032f6409e6 100644 --- a/dlls/mf/tests/mf_test.h +++ b/dlls/mf/tests/mf_test.h @@ -54,6 +54,7 @@ typedef struct attribute_desc media_type_desc[32]; #define ATTR_BLOB(k, p, n, ...) {.key = &k, .name = #k, {.vt = VT_VECTOR | VT_UI1, .caub = {.pElems = (void *)p, .cElems = n}}, __VA_ARGS__ } #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 ATTR_WSTR(k, v, ...) {.key = &k, .name = #k, {.vt = VT_LPWSTR, .pwszVal = (WCHAR *)v}, __VA_ARGS__ }
#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) diff --git a/dlls/mf/tests/multiple-streams.avi b/dlls/mf/tests/multiple-streams.avi new file mode 100644 index 0000000000000000000000000000000000000000..8ed6f1ceb6026c4db79716ff2cd96826f50a7445 GIT binary patch literal 47250 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
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/multiple-streams.mp4 b/dlls/mf/tests/multiple-streams.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..ddb005113c55889f39e3a050661ded6454340bca GIT binary patch literal 33041 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
literal 0 HcmV?d00001
diff --git a/dlls/mf/tests/resource.rc b/dlls/mf/tests/resource.rc index 10a969ff037..7808baa6baa 100644 --- a/dlls/mf/tests/resource.rc +++ b/dlls/mf/tests/resource.rc @@ -95,3 +95,56 @@ rgb32frame-grabber.bmp RCDATA rgb32frame-grabber.bmp */ /* @makedep: test.mp4 */ test.mp4 RCDATA test.mp4 + +/* Generated with: +gst-launch-1.0 videotestsrc num-buffers=60 pattern=smpte100 ! \ + taginject tags="language-code=ger" ! \ + video/x-raw,format=I420,width=72,height=72,framerate=30000/1000 ! \ + videoflip method=clockwise ! videoconvert ! x264enc ! mux. \ + \ + audiotestsrc num-buffers=60 ! audio/x-raw,format=F32LE,channels=1 ! \ + taginject tags="language-code=eng" ! \ + audioconvert ! audioresample ! avenc_aac ! mux. \ + \ + videotestsrc num-buffers=60 pattern=smpte100 ! \ + video/x-raw,format=I420,width=64,height=64,framerate=24000/1000 ! \ + videoflip method=clockwise ! videoconvert ! x264enc ! mux. \ + \ + audiotestsrc num-buffers=60 ! audio/x-raw,format=S16LE,layout=interleaved ! \ + taginject tags="language-code=fre" ! \ + audioconvert ! audioresample ! lamemp3enc ! mux. \ + \ + videotestsrc num-buffers=60 pattern=smpte100 ! \ + video/x-raw,format=I420,width=96,height=64,framerate=30000/1000 ! \ + videoflip method=clockwise ! videoconvert ! x264enc ! mux. \ + \ + mp4mux name=mux ! filesink location=dlls/mf/tests/multiple-streams.tmp && \ +ffmpeg -y -i dlls/mf/tests/multiple-streams.tmp \ + -metadata:s:v:0 title="Other Video" -metadata:s:v:2 title="First Video" \ + -metadata:s:a:0 title="This is a very long audio stream title string" \ + -codec copy -map 0 dlls/mf/tests/multiple-streams.mp4 +*/ +/* @makedep: multiple-streams.mp4 */ +multiple-streams.mp4 RCDATA multiple-streams.mp4 + +/* Generated with: +gst-launch-1.0 videotestsrc num-buffers=60 pattern=smpte100 ! \ + taginject tags="title='Video 1',language-code=ger" ! \ + video/x-raw,format=I420,width=64,height=64,framerate=30000/1001 ! \ + videoflip method=clockwise ! videoconvert ! mpeg2enc ! mux. \ + \ + audiotestsrc num-buffers=60 ! audio/x-raw,format=F32LE,channels=1 ! \ + taginject tags="language-code=eng" ! \ + audioconvert ! audioresample ! avenc_aac ! mux. \ + \ + audiotestsrc num-buffers=60 ! audio/x-raw,format=S16LE,layout=interleaved ! \ + taginject tags="language-code=fre" ! \ + audioconvert ! audioresample ! lamemp3enc ! mux. \ + \ + avimux name=mux ! filesink location=dlls/mf/tests/multiple-streams.tmp && \ +ffmpeg -y -i dlls/mf/tests/multiple-streams.tmp -metadata:s:v:0 title="Video" \ + -metadata:s:a:0 title="This is a very long audio stream title string" \ + -codec copy -map 0:a:0 -map 0:v:0 -map 0:a:1 dlls/mf/tests/multiple-streams.avi +*/ +/* @makedep: multiple-streams.avi */ +multiple-streams.avi RCDATA multiple-streams.avi diff --git a/dlls/mf/tests/transform.c b/dlls/mf/tests/transform.c index 34a00526eab..d6b75ef0d57 100644 --- a/dlls/mf/tests/transform.c +++ b/dlls/mf/tests/transform.c @@ -255,6 +255,7 @@ void check_attributes_(const char *file, int line, IMFAttributes *attributes, switch (value.vt) { default: sprintf(buffer, "??"); break; + case VT_LPWSTR: sprintf(buffer, "%s", debugstr_w(value.pwszVal)); break; case VT_CLSID: sprintf(buffer, "%s", debugstr_guid(value.puuid)); break; case VT_UI4: sprintf(buffer, "%lu", value.ulVal); break; case VT_UI8:
From: Rémi Bernon rbernon@codeweavers.com
The tests are all flaky because of the current media source design, which uses high-level GStreamer abstractions, like decodebin, which internally create threads and queues, and which cannot provide any deterministic stream ordering. --- dlls/mf/tests/mf.c | 114 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 2ff157e65d8..93da65e58c0 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -6726,11 +6726,19 @@ static void test_MFRequireProtectedEnvironment(void) ok(ref == 0, "Release returned %ld\n", ref); }
+struct stream_desc +{ + UINT id; + BOOL selected; + struct attribute_desc attributes[16]; +}; + struct presentation_desc { UINT max_required_bytes; UINT stream_count; struct attribute_desc attributes[16]; + struct stream_desc streams[16]; };
static void load_resource_stream(const WCHAR *name, IMFByteStream **stream) @@ -6765,6 +6773,7 @@ static void subtest_media_source(const WCHAR *resource, const GUID *guid, const DWORD time = 0, stream_count; QWORD bytes; HRESULT hr; + UINT i;
winetest_push_context("%s", debugstr_w(resource));
@@ -6847,6 +6856,38 @@ static void subtest_media_source(const WCHAR *resource, const GUID *guid, const todo_wine_if(stream_count == 4 && expect->stream_count == 5) ok(stream_count == expect->stream_count, "got stream_count %lu\n", stream_count); check_attributes((IMFAttributes *)presentation, expect->attributes, -1); + + for (i = 0; i < stream_count; ++i) + { + const struct stream_desc *expect_stream = expect->streams + i; + IMFMediaTypeHandler *type_handler; + IMFStreamDescriptor *stream; + DWORD id, type_count; + BOOL selected; + + winetest_push_context("%u", i); + + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(presentation, i, &selected, &stream); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine_if(!expect_stream->selected) + ok(selected == expect_stream->selected, "got selected %u\n", selected); + hr = IMFStreamDescriptor_GetStreamIdentifier(stream, &id); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(id == expect_stream->id, "got id %lu\n", id); + flaky_wine check_attributes((IMFAttributes *)stream, expect_stream->attributes, -1); + + hr = IMFStreamDescriptor_GetMediaTypeHandler(stream, &type_handler); + ok(hr == S_OK, "got hr %#lx\n", hr); + hr = IMFMediaTypeHandler_GetMediaTypeCount(type_handler, &type_count); + ok(hr == S_OK, "got hr %#lx\n", hr); + todo_wine ok(type_count == 1, "got type_count %lu\n", type_count); + + IMFMediaTypeHandler_Release(type_handler); + IMFStreamDescriptor_Release(stream); + + winetest_pop_context(); + } + IMFPresentationDescriptor_Release(presentation);
hr = IMFMediaSource_Shutdown(media_source); @@ -6878,6 +6919,52 @@ static void test_media_source(void) ATTR_RATIO(MF_PD_TOTAL_FILE_SIZE, 0, 33041, .todo = TRUE), ATTR_WSTR_OR_NONE(MF_PD_MIME_TYPE, L"video/mp4", .todo = TRUE), }, + .streams = + { + { + .id = 1, + .attributes = + { + ATTR_WSTR(MF_SD_LANGUAGE, L"fr", /* flaky, .todo = TRUE */), + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + }, + }, + { + .id = 2, + .selected = 1, + .attributes = + { + ATTR_WSTR(MF_SD_LANGUAGE, L"en", /* flaky, .todo_value = TRUE */), + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + ATTR_WSTR_OR_NONE(MF_SD_STREAM_NAME, L"This is a very long audio stream title string", .todo_value = TRUE), + }, + }, + { + .id = 3, + .attributes = + { + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + ATTR_WSTR_OR_NONE(MF_SD_STREAM_NAME, L"First Video", /* flaky, .todo = TRUE */), + }, + }, + { + .id = 4, + .attributes = + { + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + }, + }, + { + .id = 5, + .selected = 1, + .attributes = + { + ATTR_WSTR(MF_SD_LANGUAGE, L"de", /* flaky, .todo_value = TRUE */), + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + ATTR_WSTR_OR_NONE(MF_SD_STREAM_NAME, L"Other Video", /* flaky, .todo = TRUE */), + }, + }, + }, }; const struct presentation_desc avi_desc = { @@ -6891,6 +6978,33 @@ static void test_media_source(void) ATTR_UINT32(MF_PD_VIDEO_ENCODING_BITRATE, 1125200, .todo = TRUE), ATTR_WSTR_OR_NONE(MF_PD_MIME_TYPE, L"video/avi", .todo = TRUE), }, + .streams = + { + { + .id = 1, + .selected = 1, + .attributes = + { + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + ATTR_WSTR(MF_SD_STREAM_NAME, L"This is a very long audio stream title string", /* flaky, .todo = TRUE */), + }, + }, + { + .id = 2, + .selected = 1, + .attributes = + { + ATTR_WSTR(MF_SD_STREAM_NAME, L"Video", /* flaky, .todo = TRUE */), + }, + }, + { + .id = 3, + .attributes = + { + ATTR_UINT32(MF_SD_MUTUALLY_EXCLUSIVE, 1, .todo = TRUE), + }, + }, + }, }; #undef ATTR_WSTR_OR_NONE
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/winegstreamer/media_source.c | 4 ++++ 1 file changed, 4 insertions(+)
diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c index 335b617becd..f24b9a670af 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -174,7 +174,10 @@ static ULONG WINAPI source_async_command_Release(IUnknown *iface) if (!refcount) { if (command->op == SOURCE_ASYNC_START) + { + IMFPresentationDescriptor_Release(command->u.start.descriptor); PropVariantClear(&command->u.start.position); + } else if (command->op == SOURCE_ASYNC_REQUEST_SAMPLE) { if (command->u.request_sample.token) @@ -1357,6 +1360,7 @@ static HRESULT WINAPI media_source_Start(IMFMediaSource *iface, IMFPresentationD { struct source_async_command *command = impl_from_async_command_IUnknown(op); command->u.start.descriptor = descriptor; + IMFPresentationDescriptor_AddRef(descriptor); command->u.start.format = *time_format; PropVariantCopy(&command->u.start.position, position);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/mf/tests/mf.c | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-)
diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c index 93da65e58c0..603554c237d 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c @@ -1941,8 +1941,8 @@ static void wait_async_result(IMFAsyncCallback *iface, IMFAsyncResult **result) impl->result = NULL; }
-#define wait_media_event(a, b, c, d, e) wait_media_event_(__LINE__, a, b, c, d, e) -static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCallback *callback, +#define wait_media_event(a, b, c, d, e) wait_media_event_(__LINE__, (IMFMediaEventGenerator *)a, b, c, d, e) +static HRESULT wait_media_event_(int line, IMFMediaEventGenerator *session, IMFAsyncCallback *callback, MediaEventType expect_type, DWORD timeout, PROPVARIANT *value) { struct test_callback *impl = impl_from_IMFAsyncCallback(callback); @@ -1953,7 +1953,7 @@ static HRESULT wait_media_event_(int line, IMFMediaSession *session, IMFAsyncCal
do { - hr = IMFMediaSession_BeginGetEvent(session, &impl->IMFAsyncCallback_iface, (IUnknown *)session); + hr = IMFMediaEventGenerator_BeginGetEvent(session, &impl->IMFAsyncCallback_iface, (IUnknown *)session); ok_(__FILE__, line)(hr == S_OK, "Unexpected hr %#lx.\n", hr); ret = WaitForSingleObject(impl->event, timeout); ok_(__FILE__, line)(ret == WAIT_OBJECT_0, "WaitForSingleObject returned %lu\n", ret); @@ -6763,6 +6763,7 @@ static void load_resource_stream(const WCHAR *name, IMFByteStream **stream) static void subtest_media_source(const WCHAR *resource, const GUID *guid, const struct presentation_desc *expect) { IMFPresentationDescriptor *presentation; + PROPVARIANT propvar; IMFByteStreamHandler *handler; IMFMediaSource *media_source; IMFAsyncCallback *callback; @@ -6888,8 +6889,47 @@ static void subtest_media_source(const WCHAR *resource, const GUID *guid, const winetest_pop_context(); }
+ IMFAsyncCallback_Release(callback); + + + callback = create_test_callback(TRUE); + ok(!!callback, "got callback %p\n", callback); + + for (i = 0; i < stream_count; ++i) + { + hr = IMFPresentationDescriptor_DeselectStream(presentation, i); + ok(hr == S_OK, "got hr %#lx\n", hr); + } + hr = IMFPresentationDescriptor_SelectStream(presentation, 2); + ok(hr == S_OK, "got hr %#lx\n", hr); + + propvar.vt = VT_EMPTY; + hr = IMFMediaSource_Start(media_source, presentation, &GUID_NULL, &propvar); + ok(hr == S_OK, "got hr %#lx\n", hr); + IMFPresentationDescriptor_Release(presentation);
+ hr = wait_media_event(media_source, callback, MESourceStarted, INFINITE, &propvar); + ok(hr == S_OK, "got hr %#lx\n", hr); + + + hr = IMFMediaSource_CreatePresentationDescriptor(media_source, &presentation); + ok(hr == S_OK, "got hr %#lx\n", hr); + + for (i = 0; i < stream_count; ++i) + { + IMFStreamDescriptor *stream; + BOOL selected; + hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(presentation, i, &selected, &stream); + ok(hr == S_OK, "got hr %#lx\n", hr); + if (i == 2) ok(selected, "got selected %u\n", selected); + else todo_wine ok(!selected, "got selected %u\n", selected); + IMFStreamDescriptor_Release(stream); + } + + IMFPresentationDescriptor_Release(presentation); + + hr = IMFMediaSource_Shutdown(media_source); ok(hr == S_OK, "got hr %#lx\n", hr); IMFMediaSource_Release(media_source);
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132558
Your paranoid android.
=== w1064v1507 (32 bit report) ===
mf: mf.c:6838: Test failed: L"multiple-streams.mp4": Got hr 0x80004002, expected 0. mf.c:6878: Test failed: L"multiple-streams.mp4": 1: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 2: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 4: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6838: Test failed: L"multiple-streams.avi": Got hr 0x80004002, expected 0.
=== w864 (64 bit report) ===
mf: mf.c:6807: Test failed: L"multiple-streams.avi": source resolution took 46ms
=== w1064v1507 (64 bit report) ===
mf: mf.c:6838: Test failed: L"multiple-streams.mp4": Got hr 0x80004002, expected 0. mf.c:6878: Test failed: L"multiple-streams.mp4": 1: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 2: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 4: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6838: Test failed: L"multiple-streams.avi": Got hr 0x80004002, expected 0.
=== w1064v1809 (64 bit report) ===
mf: mf.c:6807: Test failed: L"multiple-streams.avi": source resolution took 31ms
=== w10pro64_en_AE_u8 (64 bit report) ===
mf: mf.c:6807: Test failed: L"multiple-streams.mp4": source resolution took 156ms
On Wed May 10 09:19:09 2023 +0000, **** wrote:
Marvin replied on the mailing list:
Hi, It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated. The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details: The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=132558 Your paranoid android. === w1064v1507 (32 bit report) === mf: mf.c:6838: Test failed: L"multiple-streams.mp4": Got hr 0x80004002, expected 0. mf.c:6878: Test failed: L"multiple-streams.mp4": 1: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 2: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 4: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6838: Test failed: L"multiple-streams.avi": Got hr 0x80004002, expected 0. === w864 (64 bit report) === mf: mf.c:6807: Test failed: L"multiple-streams.avi": source resolution took 46ms === w1064v1507 (64 bit report) === mf: mf.c:6838: Test failed: L"multiple-streams.mp4": Got hr 0x80004002, expected 0. mf.c:6878: Test failed: L"multiple-streams.mp4": 1: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 2: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6878: Test failed: L"multiple-streams.mp4": 4: "MF_SD_STREAM_NAME" missing, hr 0xc00d36e6 mf.c:6838: Test failed: L"multiple-streams.avi": Got hr 0x80004002, expected 0. === w1064v1809 (64 bit report) === mf: mf.c:6807: Test failed: L"multiple-streams.avi": source resolution took 31ms === w10pro64_en_AE_u8 (64 bit report) === mf: mf.c:6807: Test failed: L"multiple-streams.mp4": source resolution took 156ms
Of course this is something I was afraid, the testbot has a huge variance. I'll try to repeat the test a few times and take an average instead.
Nikolay Sivov (@nsivov) commented about dlls/mf/tests/mf.c:
#include "initguid.h" #include "evr9.h"
+DEFINE_GUID(CLSID_MPEG4ByteStreamHandler,0x271c3902,0x6095,0x4c45,0xa2,0x2f,0x20,0x09,0x18,0x16,0xee,0x9e); +DEFINE_GUID(CLSID_GStreamerByteStreamHandler,0x317df618,0x5e5a,0x468a,0x9f,0x15,0xd8,0x27,0xa9,0xa0,0x81,0x62);
Why do you need to create objects explicitly? Why not using the resolver?
Nikolay Sivov (@nsivov) commented about dlls/mf/tests/mf.c:
- check_interface(handler, &IID_IUnknown, TRUE);
- check_interface(handler, &IID_IMFAsyncCallback, FALSE);
- hr = IMFByteStreamHandler_GetMaxNumberOfBytesRequiredForResolution(handler, &bytes);
- todo_wine ok(hr == S_OK, "got hr %#lx\n", hr);
- load_resource_stream(resource, &stream);
- time -= GetTickCount();
- hr = IMFByteStreamHandler_BeginCreateObject(handler, stream, NULL, MF_RESOLUTION_MEDIASOURCE, NULL, NULL, callback, NULL);
- ok(hr == S_OK, "got hr %#lx\n", hr);
- wait_async_result(callback, &result);
- time += GetTickCount();
- todo_wine ok(time <= 5 || broken(time <= 20) /* testbot may be very slow */, "source resolution took %lums\n", time);
- ok(!!result, "got result %p\n", result);
Do we need such test in wine? I think we usually avoid testing things that rely on timing too much.
Nikolay Sivov (@nsivov) commented about dlls/mf/tests/mf.c:
ok(hr == S_OK, "got hr %#lx\n", hr); IMFAsyncResult_Release(result);
- check_interface(tmp_unknown, &IID_IMFMediaSource, TRUE);
- todo_wine check_interface(tmp_unknown, &IID_IMFMediaSourceEx, has_mp4_media_source && has_video_processor /* >= w10 */);
- check_interface(tmp_unknown, &IID_IMFMediaEventGenerator, TRUE);
- check_interface(tmp_unknown, &IID_IMFGetService, TRUE);
- check_service_interface(tmp_unknown, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateControl, TRUE);
- check_service_interface(tmp_unknown, &MF_RATE_CONTROL_SERVICE, &IID_IMFRateSupport, TRUE);
- /* check_service_interface(tmp_unknown, &MF_QUALITY_SERVICES, &IID_IMFQualityAdvise, TRUE); */
- /* check_service_interface(tmp_unknown, &MF_METADATA_PROVIDER_SERVICE, &IID_IMFMetadataProvider, TRUE); */
What is this for?
Nikolay Sivov (@nsivov) commented about dlls/mf/tests/mf.c:
const struct stream_desc *expect_stream = expect->streams + i;
IMFMediaTypeHandler *type_handler;
IMFStreamDescriptor *stream;
DWORD id, type_count;
BOOL selected;
winetest_push_context("%u", i);
hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(presentation, i, &selected, &stream);
ok(hr == S_OK, "got hr %#lx\n", hr);
todo_wine_if(!expect_stream->selected)
ok(selected == expect_stream->selected, "got selected %u\n", selected);
hr = IMFStreamDescriptor_GetStreamIdentifier(stream, &id);
ok(hr == S_OK, "got hr %#lx\n", hr);
todo_wine ok(id == expect_stream->id, "got id %lu\n", id);
flaky_wine check_attributes((IMFAttributes *)stream, expect_stream->attributes, -1);
Will it potentially stay flaky indefinitely?
Nikolay Sivov (@nsivov) commented about dlls/mf/tests/mf.c:
- ok(hr == S_OK, "got hr %#lx\n", hr);
- hr = IMFMediaSource_CreatePresentationDescriptor(media_source, &presentation);
- ok(hr == S_OK, "got hr %#lx\n", hr);
- for (i = 0; i < stream_count; ++i)
- {
IMFStreamDescriptor *stream;
BOOL selected;
hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(presentation, i, &selected, &stream);
ok(hr == S_OK, "got hr %#lx\n", hr);
if (i == 2) ok(selected, "got selected %u\n", selected);
else todo_wine ok(!selected, "got selected %u\n", selected);
IMFStreamDescriptor_Release(stream);
- }
Going back to that other MR. Does Clone() correctly lose selections?
On Wed May 10 14:11:24 2023 +0000, Nikolay Sivov wrote:
Will it potentially stay flaky indefinitely?
Some games expect the streams to be in a deterministic and specific order. If we want to fix them then we have to fix the flakyness.
I have some patches for that already, currently in Proton, with some intermediate step that works around wg_parser non-determinism with some stream matching heuristics. It's imperfect though, so in the end I think it means we will need a completely different backend instead of wg_parser.
The advantage would be that we could get rid of several problems inherent to the presence of Glib threads. The downsides are that we then have to rely more on MF pipeline instead of GStreamer, and afaics it's not working well yet with decoder MFTs (I believe something related to decoder MFT eating input samples without outputting anything immediately).
On Wed May 10 14:11:24 2023 +0000, Nikolay Sivov wrote:
Going back to that other MR. Does Clone() correctly lose selections?
I'm not sure what you mean, I expect that Clone would keep the selections. Currently we select all streams in the descriptor, regardless of the start descriptor. The MR that replaced Clone with as-needed instantiation doesn't change that.
On Wed May 10 14:11:23 2023 +0000, Nikolay Sivov wrote:
Do we need such test in wine? I think we usually avoid testing things that rely on timing too much.
I don't know, I think it makes the behavior difference obvious, especially in this case where timing differences break applications, and it may be fixed once the resolution is done differently. It'd also make the change more future proof, and avoid silently getting some difficult to debug playback issues back.
There is some annoying variance, which I'm not sure how to address, but I think the test is worth having as it exhibit an actual application requirement.
On Wed May 10 14:11:22 2023 +0000, Nikolay Sivov wrote:
Why do you need to create objects explicitly? Why not using the resolver?
I think it adds some unnecessary level of indirection, which would add even more variance to the timing?
On Wed May 10 14:11:23 2023 +0000, Nikolay Sivov wrote:
What is this for?
Just some basic checks about the media source implementation, and its expected interfaces. I guess they are probably tested elsewhere, but as I'm using specific classes here it was making sure every class has the same interfaces.