diff --git a/patches/protonprep-valve-staging.sh b/patches/protonprep-valve-staging.sh index 9ed360f9c..2558caa3f 100755 --- a/patches/protonprep-valve-staging.sh +++ b/patches/protonprep-valve-staging.sh @@ -322,41 +322,44 @@ patch -Np1 < ../patches/wine-gst/0009-winegstreamer-Connect-autoplug-continue-and-deep-ele.patch patch -Np1 < ../patches/wine-gst/0010-winegstreamer-Do-not-create-a-read-thread-for-uridec.patch patch -Np1 < ../patches/wine-gst/0011-winegstreamer-Ignore-an-assert-in-wg_parser.patch - patch -Np1 < ../patches/wine-gst/0012-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch - patch -Np1 < ../patches/wine-gst/0013-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch - patch -Np1 < ../patches/wine-gst/0014-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch - patch -Np1 < ../patches/wine-gst/0015-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch - patch -Np1 < ../patches/wine-gst/0016-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch - patch -Np1 < ../patches/wine-gst/0017-winegstreamer-Handle-a-duration-of-1-correctly.patch - patch -Np1 < ../patches/wine-gst/0018-winegstreamer-Don-t-only-accept-segment-events-when-.patch - patch -Np1 < ../patches/wine-gst/0019-winegstreamer-Convert-buffer-presentation-timestamps.patch - patch -Np1 < ../patches/wine-gst/0020-winegstreamer-Reorder-parser-initialization-code-a-b.patch - patch -Np1 < ../patches/wine-gst/0021-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch - patch -Np1 < ../patches/wine-gst/0022-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch - patch -Np1 < ../patches/wine-gst/0023-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch - patch -Np1 < ../patches/wine-gst/0024-winegstreamer-Do-not-seek-live-sources.patch - patch -Np1 < ../patches/wine-gst/0025-winegstreamer-Implement-buffering-events.patch - patch -Np1 < ../patches/wine-gst/0026-mf-Send-sample-requests-for-unused-space-of-sample-q.patch - patch -Np1 < ../patches/wine-gst/0027-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch - patch -Np1 < ../patches/wine-gst/0028-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch - patch -Np1 < ../patches/wine-gst/0029-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch - patch -Np1 < ../patches/wine-gst/0030-mf-session-Ensure-that-the-command-callback-does-not.patch - patch -Np1 < ../patches/wine-gst/0031-mf-session-Prevent-media-session-from-running-comman.patch - patch -Np1 < ../patches/wine-gst/0032-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch - patch -Np1 < ../patches/wine-gst/0033-winegstreamer-Also-flush-token-queue-on-seek.patch - patch -Np1 < ../patches/wine-gst/0034-mf-session-Fix-pausing-a-media-session-when-the-medi.patch - patch -Np1 < ../patches/wine-gst/0035-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch - patch -Np1 < ../patches/wine-gst/0036-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch - patch -Np1 < ../patches/wine-gst/0037-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch - patch -Np1 < ../patches/wine-gst/0038-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch - patch -Np1 < ../patches/wine-gst/0039-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch - patch -Np1 < ../patches/wine-gst/0040-Marker-commit-do-not-put-into-MR.patch - patch -Np1 < ../patches/wine-gst/0041-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch - patch -Np1 < ../patches/wine-gst/0042-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch - patch -Np1 < ../patches/wine-gst/0043-mf-Schedule-stored-timers-for-the-original-time-inst.patch - patch -Np1 < ../patches/wine-gst/0044-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch - patch -Np1 < ../patches/wine-gst/0045-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch - patch -Np1 < ../patches/wine-gst/0046-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch + patch -Np1 < ../patches/wine-gst/0012-winegstreamer-Make-wg_parser-report-the-exact-suppor.patch + patch -Np1 < ../patches/wine-gst/0013-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch + patch -Np1 < ../patches/wine-gst/0014-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch + patch -Np1 < ../patches/wine-gst/0015-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch + patch -Np1 < ../patches/wine-gst/0016-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch + patch -Np1 < ../patches/wine-gst/0017-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch + patch -Np1 < ../patches/wine-gst/0018-winegstreamer-Handle-a-duration-of-1-correctly.patch + patch -Np1 < ../patches/wine-gst/0019-winegstreamer-Don-t-only-accept-segment-events-when-.patch + patch -Np1 < ../patches/wine-gst/0020-winegstreamer-Convert-buffer-presentation-timestamps.patch + patch -Np1 < ../patches/wine-gst/0021-winegstreamer-Reorder-parser-initialization-code-a-b.patch + patch -Np1 < ../patches/wine-gst/0022-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch + patch -Np1 < ../patches/wine-gst/0023-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch + patch -Np1 < ../patches/wine-gst/0024-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch + patch -Np1 < ../patches/wine-gst/0025-winegstreamer-Do-not-seek-live-sources.patch + patch -Np1 < ../patches/wine-gst/0026-winegstreamer-Implement-buffering-events.patch + patch -Np1 < ../patches/wine-gst/0027-mf-samplegrabber-Send-sample-requests-for-unused-spa.patch + patch -Np1 < ../patches/wine-gst/0028-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch + patch -Np1 < ../patches/wine-gst/0029-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch + patch -Np1 < ../patches/wine-gst/0030-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch + patch -Np1 < ../patches/wine-gst/0031-mf-session-Ensure-that-the-command-callback-does-not.patch + patch -Np1 < ../patches/wine-gst/0032-mf-session-Prevent-media-session-from-running-comman.patch + patch -Np1 < ../patches/wine-gst/0033-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch + patch -Np1 < ../patches/wine-gst/0034-winegstreamer-Also-flush-token-queue-on-seek.patch + patch -Np1 < ../patches/wine-gst/0035-mf-session-Fix-pausing-a-media-session-when-the-medi.patch + patch -Np1 < ../patches/wine-gst/0036-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch + patch -Np1 < ../patches/wine-gst/0037-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch + patch -Np1 < ../patches/wine-gst/0038-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch + patch -Np1 < ../patches/wine-gst/0039-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch + patch -Np1 < ../patches/wine-gst/0040-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch + patch -Np1 < ../patches/wine-gst/0041-Marker-commit-do-not-put-into-MR.patch + patch -Np1 < ../patches/wine-gst/0042-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch + patch -Np1 < ../patches/wine-gst/0043-quartz-Fix-buffer-overflow-when-passing-url-as-filen.patch + patch -Np1 < ../patches/wine-gst/0044-mfplat-Allocate-memory-buffers-using-calloc.patch + patch -Np1 < ../patches/wine-gst/0045-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch + patch -Np1 < ../patches/wine-gst/0046-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch + patch -Np1 < ../patches/wine-gst/0047-mf-Schedule-stored-timers-for-the-original-time-inst.patch + patch -Np1 < ../patches/wine-gst/0048-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch + patch -Np1 < ../patches/wine-gst/0049-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch #echo "WINE: -Nvidia Reflex- Support VK_NV_low_latency2" #patch -Np1 < ../patches/proton/83-nv_low_latency_wine.patch diff --git a/patches/wine-gst/0001-mf-Add-seeking-support-for-IMFMediaSession-Start.patch b/patches/wine-gst/0001-mf-Add-seeking-support-for-IMFMediaSession-Start.patch index 79c0ad463..bb44a749f 100644 --- a/patches/wine-gst/0001-mf-Add-seeking-support-for-IMFMediaSession-Start.patch +++ b/patches/wine-gst/0001-mf-Add-seeking-support-for-IMFMediaSession-Start.patch @@ -1,14 +1,14 @@ -From 4ae3f8ceac4f38fd471db5f740e274420a9f27f5 Mon Sep 17 00:00:00 2001 +From 6d99895f2ca9e3b74de6992296e765ae286139fd Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 1 Aug 2023 10:52:21 +0800 -Subject: [PATCH 01/46] mf: Add seeking support for IMFMediaSession::Start(). +Subject: [PATCH 01/49] mf: Add seeking support for IMFMediaSession::Start(). --- dlls/mf/session.c | 57 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 6 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c -index 4f94d3c30a7..a5caad3c97a 100644 +index ef707dea4de..3f3be2b84b0 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c @@ -110,6 +110,7 @@ enum object_state @@ -19,7 +19,7 @@ index 4f94d3c30a7..a5caad3c97a 100644 OBJ_STATE_INVALID, }; -@@ -994,10 +995,28 @@ static HRESULT session_subscribe_sources(struct media_session *session) +@@ -912,10 +913,28 @@ static HRESULT session_subscribe_sources(struct media_session *session) return hr; } @@ -48,7 +48,7 @@ index 4f94d3c30a7..a5caad3c97a 100644 HRESULT hr; UINT i; -@@ -1014,6 +1033,13 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -932,6 +951,13 @@ static void session_start(struct media_session *session, const GUID *time_format /* fallthrough */ case SESSION_STATE_PAUSED: @@ -62,7 +62,7 @@ index 4f94d3c30a7..a5caad3c97a 100644 session->presentation.time_format = *time_format; session->presentation.start_position.vt = VT_EMPTY; -@@ -1027,6 +1053,14 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -945,6 +971,14 @@ static void session_start(struct media_session *session, const GUID *time_format LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry) { @@ -77,7 +77,7 @@ index 4f94d3c30a7..a5caad3c97a 100644 if (FAILED(hr = IMFMediaSource_Start(source->source, source->pd, &GUID_NULL, start_position))) { WARN("Failed to start media source %p, hr %#lx.\n", source->source, hr); -@@ -1047,12 +1081,22 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -965,12 +999,22 @@ static void session_start(struct media_session *session, const GUID *time_format } } @@ -104,7 +104,7 @@ index 4f94d3c30a7..a5caad3c97a 100644 default: session_command_complete_with_event(session, MESessionStarted, MF_E_INVALIDREQUEST, NULL); break; -@@ -2305,6 +2349,9 @@ static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format +@@ -2206,6 +2250,9 @@ static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format if (!start_position) return E_POINTER; @@ -114,7 +114,7 @@ index 4f94d3c30a7..a5caad3c97a 100644 if (FAILED(hr = create_session_op(SESSION_CMD_START, &op))) return hr; -@@ -4038,8 +4085,6 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM +@@ -3714,8 +3761,6 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM { case MESourceSeeked: case MEStreamSeeked: diff --git a/patches/wine-gst/0002-mf-tests-Add-a-create_media_session_with_source_sink.patch b/patches/wine-gst/0002-mf-tests-Add-a-create_media_session_with_source_sink.patch index a965016f5..484993fba 100644 --- a/patches/wine-gst/0002-mf-tests-Add-a-create_media_session_with_source_sink.patch +++ b/patches/wine-gst/0002-mf-tests-Add-a-create_media_session_with_source_sink.patch @@ -1,7 +1,7 @@ -From 2eeb0df8121d611c9dc8bc4552ff1ab6fd69d7c1 Mon Sep 17 00:00:00 2001 +From d2546730e1c900ceb2688ba94cb3433777099580 Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Tue, 8 Aug 2023 15:24:34 +0800 -Subject: [PATCH 02/46] mf/tests: Add a create_media_session_with_source_sink() +Subject: [PATCH 02/49] mf/tests: Add a create_media_session_with_source_sink() helper. --- @@ -9,10 +9,10 @@ Subject: [PATCH 02/46] mf/tests: Add a create_media_session_with_source_sink() 1 file changed, 48 insertions(+), 44 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index 9382d8cae35..58d8ec73c4f 100644 +index 0a34329bd75..e0bcedac20f 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c -@@ -4996,6 +4996,53 @@ static void test_sample_grabber_is_mediatype_supported(void) +@@ -4995,6 +4995,53 @@ static void test_sample_grabber_is_mediatype_supported(void) IMFSampleGrabberSinkCallback_Release(grabber_callback); } @@ -66,7 +66,7 @@ index 9382d8cae35..58d8ec73c4f 100644 static void test_sample_grabber_orientation(GUID subtype) { media_type_desc video_rgb32_desc = -@@ -5005,17 +5052,12 @@ static void test_sample_grabber_orientation(GUID subtype) +@@ -5004,17 +5051,12 @@ static void test_sample_grabber_orientation(GUID subtype) }; struct test_grabber_callback *grabber_callback; @@ -84,7 +84,7 @@ index 9382d8cae35..58d8ec73c4f 100644 HRESULT hr; DWORD res; -@@ -5036,33 +5078,6 @@ static void test_sample_grabber_orientation(GUID subtype) +@@ -5035,33 +5077,6 @@ static void test_sample_grabber_orientation(GUID subtype) grabber_callback->done_event = CreateEventW(NULL, FALSE, FALSE, NULL); ok(!!grabber_callback->done_event, "CreateEventW failed, error %lu\n", GetLastError()); @@ -118,7 +118,7 @@ index 9382d8cae35..58d8ec73c4f 100644 hr = MFCreateMediaType(&output_type); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); init_media_type(output_type, video_rgb32_desc, -1); -@@ -5070,18 +5085,7 @@ static void test_sample_grabber_orientation(GUID subtype) +@@ -5069,18 +5084,7 @@ static void test_sample_grabber_orientation(GUID subtype) ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); IMFMediaType_Release(output_type); diff --git a/patches/wine-gst/0003-mf-tests-Test-IMFMediaSession-Start.patch b/patches/wine-gst/0003-mf-tests-Test-IMFMediaSession-Start.patch index cb72978b9..f4a131c34 100644 --- a/patches/wine-gst/0003-mf-tests-Test-IMFMediaSession-Start.patch +++ b/patches/wine-gst/0003-mf-tests-Test-IMFMediaSession-Start.patch @@ -1,17 +1,17 @@ -From 9595a07ba1657ee66afd24c79dc66ee3b98c3c3f Mon Sep 17 00:00:00 2001 +From 23eb22d6b249a18679b1743f734f2c9c4bcf518f Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Mon, 7 Aug 2023 11:52:20 +0800 -Subject: [PATCH 03/46] mf/tests: Test IMFMediaSession::Start(). +Subject: [PATCH 03/49] mf/tests: Test IMFMediaSession::Start(). --- dlls/mf/tests/mf.c | 704 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 696 insertions(+), 8 deletions(-) diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c -index 58d8ec73c4f..240cbf194ea 100644 +index e0bcedac20f..f164a04b989 100644 --- a/dlls/mf/tests/mf.c +++ b/dlls/mf/tests/mf.c -@@ -2087,6 +2087,448 @@ static IMFMediaSource *create_media_source(const WCHAR *name, const WCHAR *mime) +@@ -2086,6 +2086,448 @@ static IMFMediaSource *create_media_source(const WCHAR *name, const WCHAR *mime) return source; } @@ -460,7 +460,7 @@ index 58d8ec73c4f..240cbf194ea 100644 static void test_media_session_events(void) { static const media_type_desc audio_float_44100 = -@@ -2888,27 +3330,27 @@ static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback * +@@ -2887,27 +3329,27 @@ static ULONG WINAPI test_grabber_callback_Release(IMFSampleGrabberSinkCallback * static HRESULT WINAPI test_grabber_callback_OnClockStart(IMFSampleGrabberSinkCallback *iface, MFTIME time, LONGLONG offset) { @@ -493,7 +493,7 @@ index 58d8ec73c4f..240cbf194ea 100644 } static HRESULT WINAPI test_grabber_callback_OnSetPresentationClock(IMFSampleGrabberSinkCallback *iface, -@@ -4996,9 +5438,9 @@ static void test_sample_grabber_is_mediatype_supported(void) +@@ -4995,9 +5437,9 @@ static void test_sample_grabber_is_mediatype_supported(void) IMFSampleGrabberSinkCallback_Release(grabber_callback); } @@ -505,7 +505,7 @@ index 58d8ec73c4f..240cbf194ea 100644 { IMFTopologyNode *src_node, *sink_node; IMFPresentationDescriptor *pd; -@@ -5026,6 +5468,11 @@ static void create_media_session_with_source_sink(IMFMediaSource *source, IMFAct +@@ -5025,6 +5467,11 @@ static void create_media_session_with_source_sink(IMFMediaSource *source, IMFAct hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd); ok(hr == S_OK, "Unexpected hr %#lx.\n", hr); ok(selected, "got selected %u.\n", !!selected); @@ -517,7 +517,7 @@ index 58d8ec73c4f..240cbf194ea 100644 init_source_node(source, -1, src_node, pd, sd); hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate); ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr); -@@ -5085,7 +5532,7 @@ static void test_sample_grabber_orientation(GUID subtype) +@@ -5084,7 +5531,7 @@ static void test_sample_grabber_orientation(GUID subtype) ok(hr == S_OK, "Failed to create grabber sink, hr %#lx.\n", hr); IMFMediaType_Release(output_type); @@ -526,7 +526,7 @@ index 58d8ec73c4f..240cbf194ea 100644 propvar.vt = VT_EMPTY; hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar); -@@ -7286,6 +7733,246 @@ static void test_MFCreateSequencerSegmentOffset(void) +@@ -7280,6 +7727,246 @@ static void test_MFCreateSequencerSegmentOffset(void) PropVariantClear(&propvar); } @@ -773,7 +773,7 @@ index 58d8ec73c4f..240cbf194ea 100644 START_TEST(mf) { init_functions(); -@@ -7322,4 +8009,5 @@ START_TEST(mf) +@@ -7316,4 +8003,5 @@ START_TEST(mf) test_MFRequireProtectedEnvironment(); test_mpeg4_media_sink(); test_MFCreateSequencerSegmentOffset(); diff --git a/patches/wine-gst/0004-mfmediaengine-Implement-IMFMediaEngineEx-SetCurrentT.patch b/patches/wine-gst/0004-mfmediaengine-Implement-IMFMediaEngineEx-SetCurrentT.patch index 01bf5d41b..b7b697b0d 100644 --- a/patches/wine-gst/0004-mfmediaengine-Implement-IMFMediaEngineEx-SetCurrentT.patch +++ b/patches/wine-gst/0004-mfmediaengine-Implement-IMFMediaEngineEx-SetCurrentT.patch @@ -1,7 +1,7 @@ -From 0f295094bd9483e854e2aa0a8b3c2d8fe90d77fa Mon Sep 17 00:00:00 2001 +From c9cb24b06e0d2b41d9026eeddc929474006a606d Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Fri, 28 Jul 2023 18:04:30 +0800 -Subject: [PATCH 04/46] mfmediaengine: Implement +Subject: [PATCH 04/49] mfmediaengine: Implement IMFMediaEngineEx::SetCurrentTime/Ex(). --- @@ -9,7 +9,7 @@ Subject: [PATCH 04/46] mfmediaengine: Implement 1 file changed, 47 insertions(+), 15 deletions(-) diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c -index 85b4dbb471a..6aa84e1562b 100644 +index 9e41d9dad84..28a273616c8 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c @@ -96,6 +96,7 @@ enum media_engine_flags @@ -36,7 +36,7 @@ index 85b4dbb471a..6aa84e1562b 100644 IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_PLAYING, 0, 0); break; case MESessionEnded: -@@ -1844,19 +1852,9 @@ static double WINAPI media_engine_GetCurrentTime(IMFMediaEngineEx *iface) +@@ -1846,19 +1854,9 @@ static double WINAPI media_engine_GetCurrentTime(IMFMediaEngineEx *iface) static HRESULT WINAPI media_engine_SetCurrentTime(IMFMediaEngineEx *iface, double time) { @@ -58,7 +58,7 @@ index 85b4dbb471a..6aa84e1562b 100644 } static double WINAPI media_engine_GetStartTime(IMFMediaEngineEx *iface) -@@ -3135,9 +3133,43 @@ static HRESULT WINAPI media_engine_SetRealTimeMode(IMFMediaEngineEx *iface, BOOL +@@ -3059,9 +3057,43 @@ static HRESULT WINAPI media_engine_SetRealTimeMode(IMFMediaEngineEx *iface, BOOL static HRESULT WINAPI media_engine_SetCurrentTimeEx(IMFMediaEngineEx *iface, double seektime, MF_MEDIA_ENGINE_SEEK_MODE mode) { diff --git a/patches/wine-gst/0005-mfmediaengine-tests-Test-IMFMediaEngineEx-SetCurrent.patch b/patches/wine-gst/0005-mfmediaengine-tests-Test-IMFMediaEngineEx-SetCurrent.patch index e488f7c11..3d07b0584 100644 --- a/patches/wine-gst/0005-mfmediaengine-tests-Test-IMFMediaEngineEx-SetCurrent.patch +++ b/patches/wine-gst/0005-mfmediaengine-tests-Test-IMFMediaEngineEx-SetCurrent.patch @@ -1,7 +1,7 @@ -From be4a4ae8713362505299ef8607a8df7c85ba1fbe Mon Sep 17 00:00:00 2001 +From aa917ac9bc5d31f786f16bb4d5765d53d63b50ea Mon Sep 17 00:00:00 2001 From: Zhiyi Zhang Date: Mon, 7 Aug 2023 11:53:41 +0800 -Subject: [PATCH 05/46] mfmediaengine/tests: Test +Subject: [PATCH 05/49] mfmediaengine/tests: Test IMFMediaEngineEx::SetCurrentTime/Ex(). --- @@ -9,10 +9,10 @@ Subject: [PATCH 05/46] mfmediaengine/tests: Test 1 file changed, 183 insertions(+) diff --git a/dlls/mfmediaengine/tests/mfmediaengine.c b/dlls/mfmediaengine/tests/mfmediaengine.c -index 63a7e139193..506faec231c 100644 +index 47130d8e436..29a11d034cd 100644 --- a/dlls/mfmediaengine/tests/mfmediaengine.c +++ b/dlls/mfmediaengine/tests/mfmediaengine.c -@@ -2156,6 +2156,9 @@ struct test_seek_notify +@@ -2185,6 +2185,9 @@ struct test_seek_notify { IMFMediaEngineNotify IMFMediaEngineNotify_iface; HANDLE playing_event; @@ -22,7 +22,7 @@ index 63a7e139193..506faec231c 100644 HRESULT expected_error; HRESULT error; LONG refcount; -@@ -2195,6 +2198,9 @@ static ULONG WINAPI test_seek_notify_Release(IMFMediaEngineNotify *iface) +@@ -2224,6 +2227,9 @@ static ULONG WINAPI test_seek_notify_Release(IMFMediaEngineNotify *iface) if (!refcount) { CloseHandle(notify->playing_event); @@ -32,7 +32,7 @@ index 63a7e139193..506faec231c 100644 free(notify); } -@@ -2211,6 +2217,15 @@ static HRESULT WINAPI test_seek_notify_EventNotify(IMFMediaEngineNotify *iface, +@@ -2240,6 +2246,15 @@ static HRESULT WINAPI test_seek_notify_EventNotify(IMFMediaEngineNotify *iface, case MF_MEDIA_ENGINE_EVENT_PLAYING: SetEvent(notify->playing_event); break; @@ -48,7 +48,7 @@ index 63a7e139193..506faec231c 100644 case MF_MEDIA_ENGINE_EVENT_ERROR: ok(param2 == notify->expected_error, "Unexpected error %#lx\n", param2); notify->error = param2; -@@ -2235,7 +2250,13 @@ static struct test_seek_notify *create_seek_notify(void) +@@ -2264,7 +2279,13 @@ static struct test_seek_notify *create_seek_notify(void) object = calloc(1, sizeof(*object)); object->IMFMediaEngineNotify_iface.lpVtbl = &test_seek_notify_vtbl; object->playing_event = CreateEventW(NULL, FALSE, FALSE, NULL); @@ -62,7 +62,7 @@ index 63a7e139193..506faec231c 100644 object->refcount = 1; return object; } -@@ -2481,6 +2502,167 @@ static void test_media_extension(void) +@@ -2510,6 +2531,167 @@ static void test_media_extension(void) IMFMediaEngineExtension_Release(&extension->IMFMediaEngineExtension_iface); } @@ -230,7 +230,7 @@ index 63a7e139193..506faec231c 100644 START_TEST(mfmediaengine) { HRESULT hr; -@@ -2516,6 +2698,7 @@ START_TEST(mfmediaengine) +@@ -2545,6 +2727,7 @@ START_TEST(mfmediaengine) test_GetDuration(); test_GetSeekable(); test_media_extension(); diff --git a/patches/wine-gst/0006-mfmediaengine-Implement-IMFMediaEngine-IsSeeking.patch b/patches/wine-gst/0006-mfmediaengine-Implement-IMFMediaEngine-IsSeeking.patch index 86fbb3bf1..2f85473f2 100644 --- a/patches/wine-gst/0006-mfmediaengine-Implement-IMFMediaEngine-IsSeeking.patch +++ b/patches/wine-gst/0006-mfmediaengine-Implement-IMFMediaEngine-IsSeeking.patch @@ -1,17 +1,17 @@ -From 5d422162bd10ee73d23730b54162c9b6d4fdd51d Mon Sep 17 00:00:00 2001 +From db326d9633962a78802f104d3d1eb10b4df9fd60 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 14 Jun 2024 03:09:34 +0200 -Subject: [PATCH 06/46] mfmediaengine: Implement IMFMediaEngine::IsSeeking. +Subject: [PATCH 06/49] mfmediaengine: Implement IMFMediaEngine::IsSeeking. --- dlls/mfmediaengine/main.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c -index 6aa84e1562b..fba338a8438 100644 +index 28a273616c8..a40f8d64f58 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c -@@ -1823,9 +1823,16 @@ static USHORT WINAPI media_engine_GetReadyState(IMFMediaEngineEx *iface) +@@ -1825,9 +1825,16 @@ static USHORT WINAPI media_engine_GetReadyState(IMFMediaEngineEx *iface) static BOOL WINAPI media_engine_IsSeeking(IMFMediaEngineEx *iface) { diff --git a/patches/wine-gst/0007-AVPro-Video-seeking-support.patch b/patches/wine-gst/0007-AVPro-Video-seeking-support.patch index 9ef8712c1..b21fda62f 100644 --- a/patches/wine-gst/0007-AVPro-Video-seeking-support.patch +++ b/patches/wine-gst/0007-AVPro-Video-seeking-support.patch @@ -1,17 +1,17 @@ -From 37b5a99cf5e7e2e635bc3674cf56715bef75cb83 Mon Sep 17 00:00:00 2001 +From e605d5a82a6c95cf929fa22ca4da54e51c614e4c Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 10 Apr 2024 18:57:59 +0200 -Subject: [PATCH 07/46] === AVPro Video seeking support === +Subject: [PATCH 07/49] === AVPro Video seeking support === --- MAINTAINERS | 2 ++ 1 file changed, 2 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS -index c4afb5da88c..a414cc846c8 100644 +index 59873f6804c..ab42dff2884 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -435,3 +435,5 @@ P: Zebediah Figura +@@ -436,3 +436,5 @@ P: Zebediah Figura P: Paul Gofman P: Erich E. Hoover W: https://wine-staging.com/ diff --git a/patches/wine-gst/0008-winegstreamer-Initialize-condition-variable-of-struc.patch b/patches/wine-gst/0008-winegstreamer-Initialize-condition-variable-of-struc.patch index 2add08447..81296b505 100644 --- a/patches/wine-gst/0008-winegstreamer-Initialize-condition-variable-of-struc.patch +++ b/patches/wine-gst/0008-winegstreamer-Initialize-condition-variable-of-struc.patch @@ -1,7 +1,7 @@ -From 0fb28de8800bd06d15e0d82f7a042236ea745cca Mon Sep 17 00:00:00 2001 +From 322e1f96e0f2ef1c65ab4a3d05a2ecab327dd2cb Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 14 Jun 2024 03:15:57 +0200 -Subject: [PATCH 08/46] winegstreamer: Initialize condition variable of struct +Subject: [PATCH 08/49] winegstreamer: Initialize condition variable of struct media_stream. --- @@ -9,10 +9,10 @@ Subject: [PATCH 08/46] winegstreamer: Initialize condition variable of struct 1 file changed, 1 insertion(+) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index eb6ab3d21cd..119fde3e04f 100644 +index a4ac0085dea..93a4425dd06 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1043,6 +1043,7 @@ static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor * +@@ -1172,6 +1172,7 @@ static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor * object->active = TRUE; object->eos = FALSE; object->wg_stream = wg_stream; diff --git a/patches/wine-gst/0009-winegstreamer-Connect-autoplug-continue-and-deep-ele.patch b/patches/wine-gst/0009-winegstreamer-Connect-autoplug-continue-and-deep-ele.patch index baf5d2c7c..7ac1f8cf6 100644 --- a/patches/wine-gst/0009-winegstreamer-Connect-autoplug-continue-and-deep-ele.patch +++ b/patches/wine-gst/0009-winegstreamer-Connect-autoplug-continue-and-deep-ele.patch @@ -1,18 +1,22 @@ -From 51218a2862d06d8e1dcf5a5b2cf6972d3fe9aba6 Mon Sep 17 00:00:00 2001 +From 5f965c4a5c870321b55de94b380eddbf13538a79 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Sun, 31 Mar 2024 15:49:33 +0200 -Subject: [PATCH 09/46] winegstreamer: Connect autoplug-continue and +Subject: [PATCH 09/49] winegstreamer: Connect autoplug-continue and deep-element-added callbacks to uridecodebin-based parsers too. --- - dlls/winegstreamer/wg_parser.c | 1 + - 1 file changed, 1 insertion(+) + dlls/winegstreamer/wg_parser.c | 2 ++ + 1 file changed, 2 insertions(+) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 7a6e0de7ca2..166c47720fb 100644 +index 1cd44a90e6e..e4b2d57bf7c 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -2198,6 +2198,7 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) +@@ -2102,9 +2102,11 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) + g_object_set(parser->decodebin, "uri", parser->uri, NULL); + g_signal_connect(element, "pad-added", G_CALLBACK(pad_added_cb), parser); + g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser); ++ g_signal_connect(element, "autoplug-continue", G_CALLBACK(autoplug_continue_cb), parser); g_signal_connect(element, "autoplug-select", G_CALLBACK(autoplug_select_cb), parser); g_signal_connect(element, "autoplug-sort", G_CALLBACK(autoplug_sort_cb), parser); g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser); diff --git a/patches/wine-gst/0010-winegstreamer-Do-not-create-a-read-thread-for-uridec.patch b/patches/wine-gst/0010-winegstreamer-Do-not-create-a-read-thread-for-uridec.patch index e4e20c517..5f2bedec9 100644 --- a/patches/wine-gst/0010-winegstreamer-Do-not-create-a-read-thread-for-uridec.patch +++ b/patches/wine-gst/0010-winegstreamer-Do-not-create-a-read-thread-for-uridec.patch @@ -1,7 +1,7 @@ -From 982436d84b0a409cbcfed3d205606475c5ce5b9d Mon Sep 17 00:00:00 2001 +From 50959df819d44760e3ec0e2966baad75d8ec8ab0 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 25 Mar 2024 09:19:18 +0100 -Subject: [PATCH 10/46] winegstreamer: Do not create a read thread for +Subject: [PATCH 10/49] winegstreamer: Do not create a read thread for uridecodebin-based media sources. --- @@ -9,10 +9,10 @@ Subject: [PATCH 10/46] winegstreamer: Do not create a read thread for 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 119fde3e04f..93ddf6c6051 100644 +index 93a4425dd06..6709af89444 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1501,9 +1501,12 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) +@@ -1625,9 +1625,12 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) wg_parser_disconnect(source->wg_parser); @@ -28,7 +28,7 @@ index 119fde3e04f..93ddf6c6051 100644 IMFMediaEventQueue_Shutdown(source->event_queue); IMFByteStream_Close(source->byte_stream); -@@ -1598,7 +1601,8 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc +@@ -1722,7 +1725,8 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc } object->wg_parser = parser; diff --git a/patches/wine-gst/0011-winegstreamer-Ignore-an-assert-in-wg_parser.patch b/patches/wine-gst/0011-winegstreamer-Ignore-an-assert-in-wg_parser.patch index 89b43bfa7..098dc4271 100644 --- a/patches/wine-gst/0011-winegstreamer-Ignore-an-assert-in-wg_parser.patch +++ b/patches/wine-gst/0011-winegstreamer-Ignore-an-assert-in-wg_parser.patch @@ -1,7 +1,7 @@ -From c91b169c492c84c9a73c617a5089680df130efc2 Mon Sep 17 00:00:00 2001 +From 03f5d8ca39af054cb48b9e84a9c6cda18a3bf218 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Tue, 19 Mar 2024 04:06:37 +0100 -Subject: [PATCH 11/46] winegstreamer: Ignore an assert in wg_parser. +Subject: [PATCH 11/49] winegstreamer: Ignore an assert in wg_parser. This gets hit when a wg_parser receives GST_EVENT_FLUSH_START between the wg_parser_stream_get_buffer function return and the wg_parser_stream_release_buffer call. In this case the NULL buffer can be ignored, it does no harm and there @@ -11,10 +11,10 @@ is no memory leak from this. 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 166c47720fb..c0eabd5024f 100644 +index e4b2d57bf7c..7e6d22c8e0c 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -481,11 +481,12 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) +@@ -423,11 +423,12 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) pthread_mutex_lock(&parser->mutex); diff --git a/patches/wine-gst/0012-winegstreamer-Make-wg_parser-report-the-exact-suppor.patch b/patches/wine-gst/0012-winegstreamer-Make-wg_parser-report-the-exact-suppor.patch new file mode 100644 index 000000000..2e50d51cf --- /dev/null +++ b/patches/wine-gst/0012-winegstreamer-Make-wg_parser-report-the-exact-suppor.patch @@ -0,0 +1,73 @@ +From 5e7cce5e943155c0d65ebd66d706a4d1ddaa213b Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Tue, 20 Feb 2024 23:17:28 +0100 +Subject: [PATCH 12/49] winegstreamer: Make wg_parser report the exact + supported formats to gstreamer instead of just ANY. + +--- + dlls/winegstreamer/wg_parser.c | 42 +++++++++++++++++++++++++++++++++- + 1 file changed, 41 insertions(+), 1 deletion(-) + +diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c +index 7e6d22c8e0c..b8b6f6865ee 100644 +--- a/dlls/winegstreamer/wg_parser.c ++++ b/dlls/winegstreamer/wg_parser.c +@@ -850,6 +850,43 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu + return GST_FLOW_OK; + } + ++static GstCaps *get_supported_formats(void) ++{ ++ GstCaps *caps = gst_caps_new_empty(), *temp; ++ GstAudioInfo ainfo; ++ GstVideoInfo vinfo; ++ gsize i; ++ ++ /* video/x-raw */ ++ gst_video_info_set_format(&vinfo, GST_VIDEO_FORMAT_BGRA, 1, 1); ++ temp = gst_video_info_to_caps(&vinfo); ++ for (i = 0; i < gst_caps_get_size(temp); ++i) ++ gst_structure_remove_fields(gst_caps_get_structure(temp, i), ++ "format", "width", "height", "framerate", "colorimetry", NULL); ++ gst_caps_append(caps, temp); ++ /* other formats */ ++ gst_caps_append(caps, gst_caps_new_empty_simple("video/x-cinepak")); ++ gst_caps_append(caps, gst_caps_new_simple("video/x-h264", "stream-format", G_TYPE_STRING, "byte-stream", ++ "alignment", G_TYPE_STRING, "au", NULL)); ++ gst_caps_append(caps, gst_caps_new_empty_simple("video/x-wmv")); ++ gst_caps_append(caps, gst_caps_new_empty_simple("video/x-indeo")); ++ ++ /* audio/x-raw */ ++ gst_audio_info_set_format(&ainfo, GST_AUDIO_FORMAT_S16LE, 1, 1, NULL); ++ temp = gst_audio_info_to_caps(&ainfo); ++ for (i = 0; i < gst_caps_get_size(temp); ++i) ++ gst_structure_remove_fields(gst_caps_get_structure(temp, i), ++ "format", "channels", "rate", "channel-mask", NULL); ++ gst_caps_append(caps, temp); ++ /* other formats */ ++ gst_caps_append(caps, gst_caps_new_simple("audio/mpeg", "mpegversion", G_TYPE_INT, 1, ++ "parsed", G_TYPE_BOOLEAN, TRUE, NULL)); ++ gst_caps_append(caps, gst_caps_new_simple("audio/mpeg", "mpegversion", G_TYPE_INT, 4, NULL)); ++ gst_caps_append(caps, gst_caps_new_empty_simple("audio/x-xma")); ++ ++ return caps; ++} ++ + static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) + { + struct wg_parser_stream *stream = gst_pad_get_element_private(pad); +@@ -867,7 +904,10 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) + gst_query_parse_caps(query, &filter); + + pthread_mutex_lock(&parser->mutex); +- caps = wg_format_to_caps(&stream->current_format); ++ if (stream->current_format.major_type != WG_MAJOR_TYPE_UNKNOWN) ++ caps = wg_format_to_caps(&stream->current_format); ++ else ++ caps = get_supported_formats(); + pthread_mutex_unlock(&parser->mutex); + + if (!caps) +-- +2.46.0 + diff --git a/patches/wine-gst/0012-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch b/patches/wine-gst/0013-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch similarity index 94% rename from patches/wine-gst/0012-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch rename to patches/wine-gst/0013-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch index b39a98a4b..b453fadee 100644 --- a/patches/wine-gst/0012-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch +++ b/patches/wine-gst/0013-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch @@ -1,7 +1,7 @@ -From 86de5e21e31754be6e7e68c3558b26e4f05b22ba Mon Sep 17 00:00:00 2001 +From fbec5cefbdaff199dc5bd41b872f236a8fb932c1 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:54 +0100 -Subject: [PATCH 12/46] winegstreamer: Add more RTSP-based URI schemes to +Subject: [PATCH 13/49] winegstreamer: Add more RTSP-based URI schemes to GStreamer scheme handler. --- diff --git a/patches/wine-gst/0013-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch b/patches/wine-gst/0014-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch similarity index 74% rename from patches/wine-gst/0013-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch rename to patches/wine-gst/0014-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch index 47ed850cf..20a35d87e 100644 --- a/patches/wine-gst/0013-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch +++ b/patches/wine-gst/0014-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch @@ -1,7 +1,7 @@ -From d8d66854724b8981159d96765232bf5cbcb16198 Mon Sep 17 00:00:00 2001 +From f05f2781fea1027c6c3360a8474e790c47ebf81a Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 22 Apr 2024 11:43:45 +0200 -Subject: [PATCH 13/46] winegstreamer: Mark wg_parser container bin as +Subject: [PATCH 14/49] winegstreamer: Mark wg_parser container bin as streams-aware. Mirroring wg_source. @@ -10,10 +10,10 @@ Mirroring wg_source. 1 file changed, 1 insertion(+) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index c0eabd5024f..e080312ad8f 100644 +index b8b6f6865ee..6ea25885112 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -1936,6 +1936,7 @@ static NTSTATUS wg_parser_connect(void *args) +@@ -1885,6 +1885,7 @@ static NTSTATUS wg_parser_connect(void *args) } parser->container = gst_bin_new(NULL); diff --git a/patches/wine-gst/0014-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch b/patches/wine-gst/0015-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch similarity index 78% rename from patches/wine-gst/0014-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch rename to patches/wine-gst/0015-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch index 3ccba91ab..df334ec61 100644 --- a/patches/wine-gst/0014-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch +++ b/patches/wine-gst/0015-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch @@ -1,7 +1,7 @@ -From 82fe4c734be5f209e91ceffe9e0c07b63dac11ae Mon Sep 17 00:00:00 2001 +From ff93a339ea5bf6e072f99cb265e6ad9a1ead72c2 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:55 +0100 -Subject: [PATCH 14/46] winegstreamer: Set a clock for the wg_parser pipeline. +Subject: [PATCH 15/49] winegstreamer: Set a clock for the wg_parser pipeline. Some elements under uridecodebin (e.g. the RTSP demuxer) require a valid clock to function properly. GstPipeline does this so let's do this too. @@ -10,10 +10,10 @@ GstPipeline does this so let's do this too. 1 file changed, 2 insertions(+) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index e080312ad8f..fffa5bc0a25 100644 +index 6ea25885112..2dc9ddd1f4b 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -1948,6 +1948,8 @@ static NTSTATUS wg_parser_connect(void *args) +@@ -1897,6 +1897,8 @@ static NTSTATUS wg_parser_connect(void *args) gst_pad_set_event_function(parser->my_src, src_event_cb); gst_pad_set_element_private(parser->my_src, parser); diff --git a/patches/wine-gst/0016-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch b/patches/wine-gst/0016-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch deleted file mode 100644 index 721d46569..000000000 --- a/patches/wine-gst/0016-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 2253dcd4a9acaab19f5dbb63fb79b9fa69d0f671 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Wed, 31 Jan 2024 17:42:55 +0100 -Subject: [PATCH 16/46] winegstreamer: Put pipeline into PLAYING state before - waiting for the no-more-pads callback. - -Some elements (e.g. uridecodebin with an RTSP URI) won't send no-more-pads in READY/PAUSED state. ---- - dlls/winegstreamer/wg_parser.c | 7 +++++++ - 1 file changed, 7 insertions(+) - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index fe341960229..982adfeae96 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -1977,6 +1977,13 @@ static NTSTATUS wg_parser_connect(void *args) - - pthread_mutex_lock(&parser->mutex); - -+ if (parser->uri) -+ { -+ gst_element_set_state(parser->container, GST_STATE_PLAYING); -+ ret = gst_element_get_state(parser->container, NULL, NULL, -1); -+ if (ret == GST_STATE_CHANGE_FAILURE) -+ goto out; -+ } - while (!parser_no_more_pads(parser) && !parser->error) - pthread_cond_wait(&parser->init_cond, &parser->mutex); - if (parser->error) --- -2.46.0 - diff --git a/patches/wine-gst/0015-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch b/patches/wine-gst/0016-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch similarity index 78% rename from patches/wine-gst/0015-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch rename to patches/wine-gst/0016-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch index 32720b469..e6da89345 100644 --- a/patches/wine-gst/0015-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch +++ b/patches/wine-gst/0016-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch @@ -1,7 +1,7 @@ -From 65128b0b1bb3a01a3717b6690c883df503f8c295 Mon Sep 17 00:00:00 2001 +From 1e7d1b192b3fcf946ae4d3569490886dcac1feea Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:55 +0100 -Subject: [PATCH 15/46] winegstreamer: Set base time on wg_parser bin while +Subject: [PATCH 16/49] winegstreamer: Set base time on wg_parser bin while connecting. --- @@ -9,10 +9,10 @@ Subject: [PATCH 15/46] winegstreamer: Set base time on wg_parser bin while 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index fffa5bc0a25..fe341960229 100644 +index 2dc9ddd1f4b..9b6c2ba2e9a 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -1912,6 +1912,7 @@ static NTSTATUS wg_parser_connect(void *args) +@@ -1861,6 +1861,7 @@ static NTSTATUS wg_parser_connect(void *args) const struct wg_parser_connect_params *params = args; struct wg_parser *parser = get_parser(params->parser); const WCHAR *uri = params->uri; @@ -20,7 +20,7 @@ index fffa5bc0a25..fe341960229 100644 unsigned int i; int ret; -@@ -1948,7 +1949,8 @@ static NTSTATUS wg_parser_connect(void *args) +@@ -1897,7 +1898,8 @@ static NTSTATUS wg_parser_connect(void *args) gst_pad_set_event_function(parser->my_src, src_event_cb); gst_pad_set_element_private(parser->my_src, parser); @@ -30,7 +30,7 @@ index fffa5bc0a25..fe341960229 100644 parser->start_offset = parser->next_offset = parser->stop_offset = 0; parser->next_pull_offset = 0; -@@ -1957,6 +1959,7 @@ static NTSTATUS wg_parser_connect(void *args) +@@ -1906,6 +1908,7 @@ static NTSTATUS wg_parser_connect(void *args) if (!parser->init_gst(parser)) goto out; diff --git a/patches/wine-gst/0017-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch b/patches/wine-gst/0017-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch new file mode 100644 index 000000000..d8e83ef4d --- /dev/null +++ b/patches/wine-gst/0017-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch @@ -0,0 +1,46 @@ +From b37d5bbd2ca3aa2a0bd30a22d6f923d3deab6411 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Wed, 31 Jan 2024 17:42:55 +0100 +Subject: [PATCH 17/49] winegstreamer: Put pipeline into PLAYING state before + waiting for the no-more-pads callback. + +Some elements (e.g. uridecodebin with an RTSP URI) won't send no-more-pads in READY/PAUSED state. +--- + dlls/winegstreamer/wg_parser.c | 14 +++++++++++--- + 1 file changed, 11 insertions(+), 3 deletions(-) + +diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c +index 9b6c2ba2e9a..a2fa8f494f9 100644 +--- a/dlls/winegstreamer/wg_parser.c ++++ b/dlls/winegstreamer/wg_parser.c +@@ -1909,9 +1909,9 @@ static NTSTATUS wg_parser_connect(void *args) + goto out; + + gst_element_set_base_time(parser->container, gst_clock_get_time(clock)); +- gst_element_set_state(parser->container, GST_STATE_PAUSED); +- ret = gst_element_get_state(parser->container, NULL, NULL, -1); +- ++ ret = gst_element_set_state(parser->container, GST_STATE_PAUSED); ++ if (ret == GST_STATE_CHANGE_ASYNC) ++ ret = gst_element_get_state(parser->container, NULL, NULL, -1); + if (ret == GST_STATE_CHANGE_FAILURE) + { + if (!parser->use_mediaconv && parser->init_gst == decodebin_parser_init_gst) +@@ -1926,6 +1926,14 @@ static NTSTATUS wg_parser_connect(void *args) + + pthread_mutex_lock(&parser->mutex); + ++ if (ret == GST_STATE_CHANGE_NO_PREROLL) ++ { ++ ret = gst_element_set_state(parser->container, GST_STATE_PLAYING); ++ if (ret == GST_STATE_CHANGE_ASYNC) ++ ret = gst_element_get_state(parser->container, NULL, NULL, -1); ++ if (ret == GST_STATE_CHANGE_FAILURE) ++ goto out; ++ } + while (!parser_no_more_pads(parser) && !parser->error) + pthread_cond_wait(&parser->init_cond, &parser->mutex); + if (parser->error) +-- +2.46.0 + diff --git a/patches/wine-gst/0017-winegstreamer-Handle-a-duration-of-1-correctly.patch b/patches/wine-gst/0018-winegstreamer-Handle-a-duration-of-1-correctly.patch similarity index 85% rename from patches/wine-gst/0017-winegstreamer-Handle-a-duration-of-1-correctly.patch rename to patches/wine-gst/0018-winegstreamer-Handle-a-duration-of-1-correctly.patch index 837d865f0..913fa6e72 100644 --- a/patches/wine-gst/0017-winegstreamer-Handle-a-duration-of-1-correctly.patch +++ b/patches/wine-gst/0018-winegstreamer-Handle-a-duration-of-1-correctly.patch @@ -1,7 +1,7 @@ -From c875448a508a1f60a019a5e6b26f6ef22da4d3e6 Mon Sep 17 00:00:00 2001 +From d01a36044e2625b46fb02560705daf6167836192 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Sat, 10 Aug 2024 01:43:37 +0200 -Subject: [PATCH 17/46] winegstreamer: Handle a duration of -1 correctly. +Subject: [PATCH 18/49] winegstreamer: Handle a duration of -1 correctly. Live sources will return a duration of -1 to signify that the duration is unknown. By dividing this by 100 this value gets wrongfully changed to 0. @@ -13,10 +13,10 @@ Media sources without a known duration should also not set a MF_PD_DURATION attr 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 93ddf6c6051..ce6de32d1c4 100644 +index 6709af89444..d0e9b6fdf71 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -1358,8 +1358,11 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource * +@@ -1487,8 +1487,11 @@ static HRESULT WINAPI media_source_CreatePresentationDescriptor(IMFMediaSource * hr = MF_E_SHUTDOWN; else if (SUCCEEDED(hr = MFCreatePresentationDescriptor(source->stream_count, source->descriptors, descriptor))) { @@ -31,10 +31,10 @@ index 93ddf6c6051..ce6de32d1c4 100644 for (i = 0; i < source->stream_count; ++i) { diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 982adfeae96..163c3c66b7e 100644 +index a2fa8f494f9..8bf5e1e0bde 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -2036,7 +2036,7 @@ static NTSTATUS wg_parser_connect(void *args) +@@ -1986,7 +1986,7 @@ static NTSTATUS wg_parser_connect(void *args) } if (gst_pad_peer_query_duration(stream->my_sink, GST_FORMAT_TIME, &duration)) { diff --git a/patches/wine-gst/0018-winegstreamer-Don-t-only-accept-segment-events-when-.patch b/patches/wine-gst/0019-winegstreamer-Don-t-only-accept-segment-events-when-.patch similarity index 88% rename from patches/wine-gst/0018-winegstreamer-Don-t-only-accept-segment-events-when-.patch rename to patches/wine-gst/0019-winegstreamer-Don-t-only-accept-segment-events-when-.patch index 496c16cf9..710ab26bc 100644 --- a/patches/wine-gst/0018-winegstreamer-Don-t-only-accept-segment-events-when-.patch +++ b/patches/wine-gst/0019-winegstreamer-Don-t-only-accept-segment-events-when-.patch @@ -1,7 +1,7 @@ -From aee06855814892ee1e34adebc9b95f2102449e80 Mon Sep 17 00:00:00 2001 +From e468354cc34d5f5ec74b9ea32926839a42da2a69 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Tue, 23 Apr 2024 19:30:17 +0200 -Subject: [PATCH 18/46] winegstreamer: Don't only accept segment events when +Subject: [PATCH 19/49] winegstreamer: Don't only accept segment events when streams are enabled. I don't know why this was done previously but this just creates a race condition, with no to me apparent benefit. @@ -10,10 +10,10 @@ I don't know why this was done previously but this just creates a race condition 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 163c3c66b7e..bf26f875fd0 100644 +index 8bf5e1e0bde..a3a71262b68 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -793,24 +793,20 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -698,24 +698,20 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) switch (event->type) { case GST_EVENT_SEGMENT: diff --git a/patches/wine-gst/0019-winegstreamer-Convert-buffer-presentation-timestamps.patch b/patches/wine-gst/0020-winegstreamer-Convert-buffer-presentation-timestamps.patch similarity index 87% rename from patches/wine-gst/0019-winegstreamer-Convert-buffer-presentation-timestamps.patch rename to patches/wine-gst/0020-winegstreamer-Convert-buffer-presentation-timestamps.patch index ded6260d6..18726f2a5 100644 --- a/patches/wine-gst/0019-winegstreamer-Convert-buffer-presentation-timestamps.patch +++ b/patches/wine-gst/0020-winegstreamer-Convert-buffer-presentation-timestamps.patch @@ -1,7 +1,7 @@ -From eda2f0f1be65ba35413acae0edd1e382049824bf Mon Sep 17 00:00:00 2001 +From d09d4a21ad532521c8a561227071ae6067ab12b8 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:55 +0100 -Subject: [PATCH 19/46] winegstreamer: Convert buffer presentation timestamps +Subject: [PATCH 20/49] winegstreamer: Convert buffer presentation timestamps into stream time. --- @@ -9,7 +9,7 @@ Subject: [PATCH 19/46] winegstreamer: Convert buffer presentation timestamps 1 file changed, 40 insertions(+), 16 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index bf26f875fd0..54e7f81b105 100644 +index a3a71262b68..fd678f111e0 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -86,7 +86,7 @@ struct wg_parser @@ -21,7 +21,7 @@ index bf26f875fd0..54e7f81b105 100644 bool err_on, warn_on; pthread_cond_t read_cond, read_done_cond; -@@ -378,6 +378,18 @@ static GstBuffer *wait_parser_stream_buffer(struct wg_parser *parser, struct wg_ +@@ -320,6 +320,18 @@ static GstBuffer *wait_parser_stream_buffer(struct wg_parser *parser, struct wg_ return buffer; } @@ -40,7 +40,7 @@ index bf26f875fd0..54e7f81b105 100644 static NTSTATUS wg_parser_stream_get_buffer(void *args) { const struct wg_parser_stream_get_buffer_params *params = args; -@@ -389,6 +401,7 @@ static NTSTATUS wg_parser_stream_get_buffer(void *args) +@@ -331,6 +343,7 @@ static NTSTATUS wg_parser_stream_get_buffer(void *args) pthread_mutex_lock(&parser->mutex); @@ -48,7 +48,7 @@ index bf26f875fd0..54e7f81b105 100644 if (stream) buffer = wait_parser_stream_buffer(parser, stream); else -@@ -431,13 +444,24 @@ static NTSTATUS wg_parser_stream_get_buffer(void *args) +@@ -373,13 +386,24 @@ static NTSTATUS wg_parser_stream_get_buffer(void *args) return S_FALSE; } @@ -79,7 +79,7 @@ index bf26f875fd0..54e7f81b105 100644 if ((wg_buffer->has_duration = GST_BUFFER_DURATION_IS_VALID(buffer))) wg_buffer->duration = GST_BUFFER_DURATION(buffer) / 100; wg_buffer->discontinuity = GST_BUFFER_FLAG_IS_SET(buffer, GST_BUFFER_FLAG_DISCONT); -@@ -480,16 +504,8 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) +@@ -422,16 +446,8 @@ static NTSTATUS wg_parser_stream_release_buffer(void *args) struct wg_parser *parser = stream->parser; pthread_mutex_lock(&parser->mutex); @@ -97,7 +97,7 @@ index bf26f875fd0..54e7f81b105 100644 return S_OK; } -@@ -548,6 +564,8 @@ static NTSTATUS wg_parser_stream_seek(void *args) +@@ -490,6 +506,8 @@ static NTSTATUS wg_parser_stream_seek(void *args) flags, start_type, params->start_pos * 100, stop_type, params->stop_pos == stream->duration ? -1 : params->stop_pos * 100))) GST_ERROR("Failed to seek."); @@ -106,7 +106,7 @@ index bf26f875fd0..54e7f81b105 100644 return S_OK; } -@@ -795,6 +813,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -700,6 +718,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) case GST_EVENT_SEGMENT: { const GstSegment *segment; @@ -114,7 +114,7 @@ index bf26f875fd0..54e7f81b105 100644 gst_event_parse_segment(event, &segment); if (segment->format != GST_FORMAT_TIME) -@@ -803,7 +822,12 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -708,7 +727,12 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) break; } pthread_mutex_lock(&parser->mutex); diff --git a/patches/wine-gst/0020-winegstreamer-Reorder-parser-initialization-code-a-b.patch b/patches/wine-gst/0021-winegstreamer-Reorder-parser-initialization-code-a-b.patch similarity index 87% rename from patches/wine-gst/0020-winegstreamer-Reorder-parser-initialization-code-a-b.patch rename to patches/wine-gst/0021-winegstreamer-Reorder-parser-initialization-code-a-b.patch index 56bc95561..2ed793a56 100644 --- a/patches/wine-gst/0020-winegstreamer-Reorder-parser-initialization-code-a-b.patch +++ b/patches/wine-gst/0021-winegstreamer-Reorder-parser-initialization-code-a-b.patch @@ -1,7 +1,7 @@ -From 28164789e9edeb964df886636f719ef3a307bf01 Mon Sep 17 00:00:00 2001 +From a6e00f61b2dd22d948fc77f2d2b893cfe5bd4416 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:55 +0100 -Subject: [PATCH 20/46] winegstreamer: Reorder parser initialization code a bit +Subject: [PATCH 21/49] winegstreamer: Reorder parser initialization code a bit to prevent race conditions. --- @@ -9,10 +9,10 @@ Subject: [PATCH 20/46] winegstreamer: Reorder parser initialization code a bit 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 54e7f81b105..0ba9b2f81f4 100644 +index fd678f111e0..6f656db98c1 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -2195,7 +2195,10 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser) +@@ -2145,7 +2145,10 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser) gst_bin_add(GST_BIN(parser->container), element); parser->decodebin = element; @@ -24,7 +24,7 @@ index 54e7f81b105..0ba9b2f81f4 100644 g_signal_connect(element, "pad-added", G_CALLBACK(pad_added_cb), parser); g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser); g_signal_connect(element, "autoplug-continue", G_CALLBACK(autoplug_continue_cb), parser); -@@ -2203,10 +2206,7 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser) +@@ -2153,10 +2156,7 @@ static BOOL decodebin_parser_init_gst(struct wg_parser *parser) g_signal_connect(element, "autoplug-sort", G_CALLBACK(autoplug_sort_cb), parser); g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser); g_signal_connect(element, "deep-element-added", G_CALLBACK(deep_element_added_cb), parser); @@ -36,7 +36,7 @@ index 54e7f81b105..0ba9b2f81f4 100644 if (!link_src_to_element(parser->my_src, element)) return FALSE; -@@ -2225,7 +2225,10 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) +@@ -2174,7 +2174,10 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) gst_bin_add(GST_BIN(parser->container), element); parser->decodebin = element; @@ -48,7 +48,7 @@ index 54e7f81b105..0ba9b2f81f4 100644 g_signal_connect(element, "pad-added", G_CALLBACK(pad_added_cb), parser); g_signal_connect(element, "pad-removed", G_CALLBACK(pad_removed_cb), parser); g_signal_connect(element, "autoplug-continue", G_CALLBACK(autoplug_continue_cb), parser); -@@ -2233,10 +2236,7 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) +@@ -2182,10 +2185,7 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) g_signal_connect(element, "autoplug-sort", G_CALLBACK(autoplug_sort_cb), parser); g_signal_connect(element, "no-more-pads", G_CALLBACK(no_more_pads_cb), parser); g_signal_connect(element, "deep-element-added", G_CALLBACK(deep_element_added_cb), parser); @@ -60,7 +60,7 @@ index 54e7f81b105..0ba9b2f81f4 100644 return TRUE; } -@@ -2250,14 +2250,14 @@ static BOOL avi_parser_init_gst(struct wg_parser *parser) +@@ -2199,14 +2199,14 @@ static BOOL avi_parser_init_gst(struct wg_parser *parser) gst_bin_add(GST_BIN(parser->container), element); diff --git a/patches/wine-gst/0021-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch b/patches/wine-gst/0022-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch similarity index 78% rename from patches/wine-gst/0021-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch rename to patches/wine-gst/0022-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch index af52b7f5d..7ff3376a6 100644 --- a/patches/wine-gst/0021-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch +++ b/patches/wine-gst/0022-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch @@ -1,7 +1,7 @@ -From 430c42b86bbee46371aafb14ed670bfcf5550b82 Mon Sep 17 00:00:00 2001 +From 8ce5fc567d6366479f03c6aa2632c61ecdacd162 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:54 +0100 -Subject: [PATCH 21/46] winegstreamer: Do away with the per-stream condvars and +Subject: [PATCH 22/49] winegstreamer: Do away with the per-stream condvars and use one parser-wide condvar instead. --- @@ -9,7 +9,7 @@ Subject: [PATCH 21/46] winegstreamer: Do away with the per-stream condvars and 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 0ba9b2f81f4..1d6367abd3b 100644 +index 6f656db98c1..293671a9c08 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -90,6 +90,7 @@ struct wg_parser @@ -20,17 +20,17 @@ index 0ba9b2f81f4..1d6367abd3b 100644 struct { GstBuffer *buffer; -@@ -124,7 +125,6 @@ struct wg_parser_stream - GstCaps *current_caps; - GstCaps *desired_caps; +@@ -122,7 +123,6 @@ struct wg_parser_stream + GstSegment segment; + struct wg_format preferred_format, current_format, codec_format; - pthread_cond_t event_cond, event_empty_cond; GstBuffer *buffer; GstMapInfo map_info; -@@ -360,8 +360,7 @@ static NTSTATUS wg_parser_stream_disable(void *args) - stream->desired_caps = NULL; - } +@@ -302,8 +302,7 @@ static NTSTATUS wg_parser_stream_disable(void *args) + stream->enabled = false; + stream->current_format.major_type = WG_MAJOR_TYPE_UNKNOWN; pthread_mutex_unlock(&parser->mutex); - pthread_cond_signal(&stream->event_cond); - pthread_cond_signal(&stream->event_empty_cond); @@ -38,7 +38,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 return S_OK; } -@@ -373,7 +372,7 @@ static GstBuffer *wait_parser_stream_buffer(struct wg_parser *parser, struct wg_ +@@ -315,7 +314,7 @@ static GstBuffer *wait_parser_stream_buffer(struct wg_parser *parser, struct wg_ * must return the buffer. */ while (stream->enabled && !(buffer = stream->buffer) && !stream->eos) @@ -47,7 +47,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 return buffer; } -@@ -387,7 +386,7 @@ static void release_buffer(struct wg_parser *parser, struct wg_parser_stream *st +@@ -329,7 +328,7 @@ static void release_buffer(struct wg_parser *parser, struct wg_parser_stream *st stream->buffer = NULL; } @@ -56,7 +56,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 } static NTSTATUS wg_parser_stream_get_buffer(void *args) -@@ -836,7 +835,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -741,7 +740,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) pthread_mutex_lock(&parser->mutex); stream->eos = true; if (stream->enabled) @@ -65,7 +65,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 else pthread_cond_signal(&parser->init_cond); pthread_mutex_unlock(&parser->mutex); -@@ -848,7 +847,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -753,7 +752,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) if (stream->enabled) { stream->flushing = true; @@ -74,7 +74,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 if (stream->buffer) { -@@ -925,7 +924,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu +@@ -831,7 +830,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu * implementing a queue object here. */ while (stream->enabled && !stream->flushing && stream->buffer) @@ -83,7 +83,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 if (!stream->enabled) { -@@ -954,7 +953,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu +@@ -860,7 +859,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu stream->buffer = buffer; pthread_mutex_unlock(&parser->mutex); @@ -92,16 +92,16 @@ index 0ba9b2f81f4..1d6367abd3b 100644 /* The chain callback is given a reference to the buffer. Transfer that * reference to the stream object, which will release it in -@@ -1059,8 +1058,6 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser, char *id - stream->parser = parser; +@@ -1004,8 +1003,6 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser, char *id stream->number = parser->stream_count; stream->no_more_pads = true; + stream->current_format.major_type = WG_MAJOR_TYPE_UNKNOWN; - pthread_cond_init(&stream->event_cond, NULL); - pthread_cond_init(&stream->event_empty_cond, NULL); sprintf(pad_name, "qz_sink_%u", parser->stream_count); stream->my_sink = gst_pad_new(pad_name, GST_PAD_SINK); -@@ -1092,9 +1089,6 @@ static void free_stream(struct wg_parser_stream *stream) +@@ -1037,9 +1034,6 @@ static void free_stream(struct wg_parser_stream *stream) stream->buffer = NULL; } @@ -111,7 +111,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 for (i = 0; i < ARRAY_SIZE(stream->tags); ++i) { if (stream->tags[i]) -@@ -2146,10 +2140,8 @@ static NTSTATUS wg_parser_disconnect(void *args) +@@ -2096,10 +2090,8 @@ static NTSTATUS wg_parser_disconnect(void *args) /* Unblock all of our streams. */ pthread_mutex_lock(&parser->mutex); for (i = 0; i < parser->stream_count; ++i) @@ -123,7 +123,7 @@ index 0ba9b2f81f4..1d6367abd3b 100644 pthread_mutex_unlock(&parser->mutex); gst_element_set_state(parser->container, GST_STATE_NULL); -@@ -2326,6 +2318,7 @@ static NTSTATUS wg_parser_create(void *args) +@@ -2275,6 +2267,7 @@ static NTSTATUS wg_parser_create(void *args) pthread_cond_init(&parser->init_cond, NULL); pthread_cond_init(&parser->read_cond, NULL); pthread_cond_init(&parser->read_done_cond, NULL); diff --git a/patches/wine-gst/0023-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch b/patches/wine-gst/0023-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch deleted file mode 100644 index b6e62443a..000000000 --- a/patches/wine-gst/0023-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch +++ /dev/null @@ -1,242 +0,0 @@ -From 7e6827b0d6e4609485224e3e4a454072fea256c8 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Tue, 19 Mar 2024 10:09:59 +0100 -Subject: [PATCH 23/46] winegstreamer: Do not fail caps negotiation when - there's a concurrent reconfigure. - -If wg_parser_stream_enable is called between the time our sink's GST_QUERY_CAPS returns and the time our sink gets the -GST_QUERY_ACCEPT_CAPS query to finalize caps negotiation, GST_QUERY_ACCEPT_CAPS would likely return FALSE because the -caps that are being negotiated would not meet the requirements of the new stream->current_format set by -wg_parser_stream_enable. - -Instead, accept both the old and the new format as valid caps in GST_QUERY_ACCEPT_CAPS, but discard buffers until the -correct caps have been negotiated (signalled by a GST_EVENT_CAPS). - -Also try to omit the reconfigure event in some cases. ---- - dlls/winegstreamer/wg_parser.c | 107 ++++++++++++++++++++++++++++++--- - 1 file changed, 99 insertions(+), 8 deletions(-) - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index ef89d506bf6..11b4d4f915a 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -124,6 +124,7 @@ struct wg_parser_stream - GstCaps *codec_caps; - GstCaps *current_caps; - GstCaps *desired_caps; -+ GstCaps *next_desired_caps; - - GstBuffer *buffer; - GstMapInfo map_info; -@@ -298,16 +299,53 @@ static NTSTATUS wg_parser_stream_get_codec_format(void *args) - return S_OK; - } - -+static BOOL stream_set_next_caps(struct wg_parser_stream *stream, GstCaps *caps) -+{ -+ struct wg_parser *parser = stream->parser; -+ -+ while (stream->next_desired_caps && !parser->error) -+ pthread_cond_wait(&parser->stream_event_cond, &parser->mutex); -+ -+ if (parser->error) -+ { -+ pthread_mutex_unlock(&parser->mutex); -+ return E_FAIL; -+ } -+ -+ if (!(stream->current_caps && gst_caps_is_equal(stream->current_caps, caps))) -+ { -+ if (stream->desired_caps) -+ { -+ if (!gst_caps_is_equal(stream->desired_caps, caps)) -+ { -+ stream->next_desired_caps = caps; -+ return !!stream->current_caps; -+ } -+ } -+ else -+ stream->desired_caps = caps; -+ return TRUE; -+ } -+ else if (!(stream->desired_caps && gst_caps_is_equal(stream->desired_caps, caps))) -+ { -+ stream->desired_caps = caps; -+ return FALSE; -+ } -+ gst_caps_unref(caps); -+ return FALSE; -+} -+ - static NTSTATUS wg_parser_stream_enable(void *args) - { - const struct wg_parser_stream_enable_params *params = args; - struct wg_parser_stream *stream = get_stream(params->stream); - const struct wg_format *format = params->format; - struct wg_parser *parser = stream->parser; -+ BOOL need_reconf; - - pthread_mutex_lock(&parser->mutex); - -- stream->desired_caps = wg_format_to_caps(format); -+ need_reconf = stream_set_next_caps(stream, wg_format_to_caps(format)); - stream->enabled = true; - - pthread_mutex_unlock(&parser->mutex); -@@ -315,11 +353,18 @@ static NTSTATUS wg_parser_stream_enable(void *args) - if (format->major_type == WG_MAJOR_TYPE_VIDEO) - { - bool flip = (format->u.video.height < 0); -+ GstVideoOrientationMethod old_method = -1, new_method = flip ? GST_VIDEO_ORIENTATION_VERT : GST_VIDEO_ORIENTATION_IDENTITY; - -- gst_util_set_object_arg(G_OBJECT(stream->flip), "method", flip ? "vertical-flip" : "none"); -+ g_object_get(G_OBJECT(stream->flip), "method", &old_method, NULL); -+ if (new_method != old_method) -+ { -+ g_object_set(G_OBJECT(stream->flip), "method", new_method, NULL); -+ need_reconf = TRUE; -+ } - } - -- push_event(stream->my_sink, gst_event_new_reconfigure()); -+ if (need_reconf) -+ push_event(stream->my_sink, gst_event_new_reconfigure()); - return S_OK; - } - -@@ -328,10 +373,11 @@ static NTSTATUS wg_parser_stream_enable_type(void *args) - const struct wg_parser_stream_enable_type_params *params = args; - struct wg_parser_stream *stream = get_stream(params->stream); - struct wg_parser *parser = stream->parser; -+ BOOL need_reconf; - - pthread_mutex_lock(&parser->mutex); - -- stream->desired_caps = caps_from_media_type(¶ms->media_type); -+ need_reconf = stream_set_next_caps(stream, caps_from_media_type(¶ms->media_type)); - stream->enabled = true; - - pthread_mutex_unlock(&parser->mutex); -@@ -339,11 +385,18 @@ static NTSTATUS wg_parser_stream_enable_type(void *args) - if (IsEqualGUID(¶ms->media_type.major, &MEDIATYPE_Video) && stream->flip) - { - bool flip = !!(params->media_type.u.video->videoInfo.VideoFlags & MFVideoFlag_BottomUpLinearRep); -+ GstVideoOrientationMethod old_method = -1, new_method = flip ? GST_VIDEO_ORIENTATION_VERT : GST_VIDEO_ORIENTATION_IDENTITY; - -- gst_util_set_object_arg(G_OBJECT(stream->flip), "method", flip ? "vertical-flip" : "none"); -+ g_object_get(G_OBJECT(stream->flip), "method", &old_method, NULL); -+ if (new_method != old_method) -+ { -+ g_object_set(G_OBJECT(stream->flip), "method", new_method, NULL); -+ need_reconf = TRUE; -+ } - } - -- push_event(stream->my_sink, gst_event_new_reconfigure()); -+ if (need_reconf) -+ push_event(stream->my_sink, gst_event_new_reconfigure()); - return S_OK; - } - -@@ -359,6 +412,11 @@ static NTSTATUS wg_parser_stream_disable(void *args) - gst_caps_unref(stream->desired_caps); - stream->desired_caps = NULL; - } -+ if (stream->next_desired_caps) -+ { -+ gst_caps_unref(stream->next_desired_caps); -+ stream->next_desired_caps = NULL; -+ } - pthread_mutex_unlock(&parser->mutex); - pthread_cond_broadcast(&parser->stream_event_cond); - return S_OK; -@@ -886,6 +944,16 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) - gst_event_parse_caps(event, &caps); - pthread_mutex_lock(&parser->mutex); - stream->current_caps = gst_caps_ref(caps); -+ if (stream->next_desired_caps) -+ { -+ if (!gst_caps_can_intersect(stream->current_caps, stream->next_desired_caps)) -+ push_event(stream->my_sink, gst_event_new_reconfigure()); -+ else -+ { -+ stream->next_desired_caps = NULL; -+ pthread_cond_broadcast(&parser->stream_event_cond); -+ } -+ } - pthread_mutex_unlock(&parser->mutex); - pthread_cond_signal(&parser->init_cond); - break; -@@ -914,6 +982,14 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu - - pthread_mutex_lock(&parser->mutex); - -+ if (stream->next_desired_caps) -+ { -+ GST_DEBUG("Stream is changing format; discarding buffer."); -+ pthread_mutex_unlock(&parser->mutex); -+ gst_buffer_unref(buffer); -+ return GST_FLOW_OK; -+ } -+ - if (!stream->has_buffer) - { - stream->has_buffer = true; -@@ -980,7 +1056,15 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - gst_query_parse_caps(query, &filter); - - pthread_mutex_lock(&parser->mutex); -- if (!stream->desired_caps || !(caps = gst_caps_copy(stream->desired_caps))) -+ if (stream->next_desired_caps) -+ { -+ if (!(caps = gst_caps_copy(stream->next_desired_caps))) -+ { -+ pthread_mutex_unlock(&parser->mutex); -+ return FALSE; -+ } -+ } -+ else if (!stream->desired_caps || !(caps = gst_caps_copy(stream->desired_caps))) - { - pthread_mutex_unlock(&parser->mutex); - return FALSE; -@@ -1014,7 +1098,7 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - - pthread_mutex_lock(&parser->mutex); - -- if (!stream->desired_caps) -+ if (!stream->desired_caps || !stream->next_desired_caps) - { - pthread_mutex_unlock(&parser->mutex); - gst_query_set_accept_caps_result(query, TRUE); -@@ -1025,6 +1109,11 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) - wg_format_from_caps(&format, caps); - wg_format_from_caps(¤t_format, stream->desired_caps); - ret = wg_format_compare(&format, ¤t_format); -+ if (!ret) -+ { -+ wg_format_from_caps(¤t_format, stream->next_desired_caps); -+ ret = wg_format_compare(&format, ¤t_format); -+ } - - pthread_mutex_unlock(&parser->mutex); - -@@ -1711,6 +1800,7 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use - parser->error = true; - pthread_mutex_unlock(&parser->mutex); - pthread_cond_signal(&parser->init_cond); -+ pthread_cond_broadcast(&parser->stream_event_cond); - break; - - case GST_MESSAGE_WARNING: -@@ -1741,6 +1831,7 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use - GST_WARNING("Autoplugged element failed to initialise, trying again with protonvideoconvert."); - parser->error = true; - pthread_cond_signal(&parser->init_cond); -+ pthread_cond_broadcast(&parser->stream_event_cond); - } - pthread_mutex_unlock(&parser->mutex); - } --- -2.46.0 - diff --git a/patches/wine-gst/0022-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch b/patches/wine-gst/0023-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch similarity index 78% rename from patches/wine-gst/0022-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch rename to patches/wine-gst/0023-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch index 625dc822b..11521f02d 100644 --- a/patches/wine-gst/0022-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch +++ b/patches/wine-gst/0023-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch @@ -1,7 +1,7 @@ -From 13c03e805550b1ba978ae8c4e6ce85fe0b3b6eb5 Mon Sep 17 00:00:00 2001 +From 31c788f0093a57a8e8195eb4bd4047afe527397f Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 18 Mar 2024 10:18:07 +0100 -Subject: [PATCH 22/46] winegstreamer: Use pthread_cond_broadcast instead of +Subject: [PATCH 23/49] winegstreamer: Use pthread_cond_broadcast instead of pthread_cond_signal for stream_event_cond. --- @@ -9,19 +9,19 @@ Subject: [PATCH 22/46] winegstreamer: Use pthread_cond_broadcast instead of 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 1d6367abd3b..ef89d506bf6 100644 +index 293671a9c08..56acd04d39c 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -360,7 +360,7 @@ static NTSTATUS wg_parser_stream_disable(void *args) - stream->desired_caps = NULL; - } +@@ -302,7 +302,7 @@ static NTSTATUS wg_parser_stream_disable(void *args) + stream->enabled = false; + stream->current_format.major_type = WG_MAJOR_TYPE_UNKNOWN; pthread_mutex_unlock(&parser->mutex); - pthread_cond_signal(&parser->stream_event_cond); + pthread_cond_broadcast(&parser->stream_event_cond); return S_OK; } -@@ -386,7 +386,7 @@ static void release_buffer(struct wg_parser *parser, struct wg_parser_stream *st +@@ -328,7 +328,7 @@ static void release_buffer(struct wg_parser *parser, struct wg_parser_stream *st stream->buffer = NULL; } @@ -30,7 +30,7 @@ index 1d6367abd3b..ef89d506bf6 100644 } static NTSTATUS wg_parser_stream_get_buffer(void *args) -@@ -835,7 +835,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -740,7 +740,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) pthread_mutex_lock(&parser->mutex); stream->eos = true; if (stream->enabled) @@ -39,7 +39,7 @@ index 1d6367abd3b..ef89d506bf6 100644 else pthread_cond_signal(&parser->init_cond); pthread_mutex_unlock(&parser->mutex); -@@ -847,7 +847,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -752,7 +752,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) if (stream->enabled) { stream->flushing = true; @@ -48,7 +48,7 @@ index 1d6367abd3b..ef89d506bf6 100644 if (stream->buffer) { -@@ -953,7 +953,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu +@@ -859,7 +859,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu stream->buffer = buffer; pthread_mutex_unlock(&parser->mutex); @@ -57,7 +57,7 @@ index 1d6367abd3b..ef89d506bf6 100644 /* The chain callback is given a reference to the buffer. Transfer that * reference to the stream object, which will release it in -@@ -2141,7 +2141,7 @@ static NTSTATUS wg_parser_disconnect(void *args) +@@ -2091,7 +2091,7 @@ static NTSTATUS wg_parser_disconnect(void *args) pthread_mutex_lock(&parser->mutex); for (i = 0; i < parser->stream_count; ++i) parser->streams[i]->flushing = true; diff --git a/patches/wine-gst/0024-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch b/patches/wine-gst/0024-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch new file mode 100644 index 000000000..06c3a3cf0 --- /dev/null +++ b/patches/wine-gst/0024-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch @@ -0,0 +1,194 @@ +From 689c09959e19f7e9359a8930ac8b4ddd878efc46 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Tue, 19 Mar 2024 10:09:59 +0100 +Subject: [PATCH 24/49] winegstreamer: Do not fail caps negotiation when + there's a concurrent reconfigure. + +If wg_parser_stream_enable is called between the time our sink's GST_QUERY_CAPS returns and the time our sink gets the +GST_QUERY_ACCEPT_CAPS query to finalize caps negotiation, GST_QUERY_ACCEPT_CAPS would likely return FALSE because the +caps that are being negotiated would not meet the requirements of the new stream->current_format set by +wg_parser_stream_enable. + +Instead, accept both the old and the new format as valid caps in GST_QUERY_ACCEPT_CAPS, but discard buffers until the +correct caps have been negotiated (signalled by a GST_EVENT_CAPS). + +Also try to omit the reconfigure event in some cases. +--- + dlls/winegstreamer/wg_parser.c | 72 +++++++++++++++++++++++++++++++--- + 1 file changed, 66 insertions(+), 6 deletions(-) + +diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c +index 56acd04d39c..d6e42c3d815 100644 +--- a/dlls/winegstreamer/wg_parser.c ++++ b/dlls/winegstreamer/wg_parser.c +@@ -121,7 +121,7 @@ struct wg_parser_stream + GstPad *my_sink; + GstElement *flip, *decodebin; + GstSegment segment; +- struct wg_format preferred_format, current_format, codec_format; ++ struct wg_format preferred_format, current_format, next_format, codec_format; + + GstBuffer *buffer; + GstMapInfo map_info; +@@ -268,16 +268,41 @@ static NTSTATUS wg_parser_stream_get_codec_format(void *args) + return S_OK; + } + ++static BOOL stream_set_next_caps(struct wg_parser_stream *stream, const struct wg_format *format) ++{ ++ struct wg_parser *parser = stream->parser; ++ ++ while (stream->next_format.major_type != WG_MAJOR_TYPE_UNKNOWN && !parser->error) ++ pthread_cond_wait(&parser->stream_event_cond, &parser->mutex); ++ ++ if (parser->error) ++ { ++ pthread_mutex_unlock(&parser->mutex); ++ return E_FAIL; ++ } ++ ++ if (!wg_format_compare(&stream->current_format, format) ++ && !(stream->has_caps && wg_format_compare(&stream->preferred_format, format))) ++ { ++ stream->next_format = *format; ++ return stream->has_caps; ++ } ++ else ++ stream->current_format = *format; ++ return FALSE; ++} ++ + static NTSTATUS wg_parser_stream_enable(void *args) + { + const struct wg_parser_stream_enable_params *params = args; + struct wg_parser_stream *stream = get_stream(params->stream); + const struct wg_format *format = params->format; + struct wg_parser *parser = stream->parser; ++ BOOL need_reconf = FALSE; + + pthread_mutex_lock(&parser->mutex); + +- stream->current_format = *format; ++ need_reconf = stream_set_next_caps(stream, format); + stream->enabled = true; + + pthread_mutex_unlock(&parser->mutex); +@@ -285,11 +310,18 @@ static NTSTATUS wg_parser_stream_enable(void *args) + if (format->major_type == WG_MAJOR_TYPE_VIDEO) + { + bool flip = (params->flags & STREAM_ENABLE_FLAG_FLIP_RGB) && (format->u.video.height < 0); ++ GstVideoOrientationMethod old_method = -1, new_method = flip ? GST_VIDEO_ORIENTATION_VERT : GST_VIDEO_ORIENTATION_IDENTITY; + +- gst_util_set_object_arg(G_OBJECT(stream->flip), "method", flip ? "vertical-flip" : "none"); ++ g_object_get(G_OBJECT(stream->flip), "method", &old_method, NULL); ++ if (new_method != old_method) ++ { ++ g_object_set(G_OBJECT(stream->flip), "method", new_method, NULL); ++ need_reconf = TRUE; ++ } + } + +- push_event(stream->my_sink, gst_event_new_reconfigure()); ++ if (need_reconf) ++ push_event(stream->my_sink, gst_event_new_reconfigure()); + return S_OK; + } + +@@ -301,6 +333,7 @@ static NTSTATUS wg_parser_stream_disable(void *args) + pthread_mutex_lock(&parser->mutex); + stream->enabled = false; + stream->current_format.major_type = WG_MAJOR_TYPE_UNKNOWN; ++ stream->next_format.major_type = WG_MAJOR_TYPE_UNKNOWN; + pthread_mutex_unlock(&parser->mutex); + pthread_cond_broadcast(&parser->stream_event_cond); + return S_OK; +@@ -792,6 +825,17 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) + pthread_mutex_lock(&parser->mutex); + wg_format_from_caps(&stream->preferred_format, caps); + stream->has_caps = true; ++ if (stream->next_format.major_type != WG_MAJOR_TYPE_UNKNOWN) ++ { ++ if (!wg_format_compare(&stream->preferred_format, &stream->next_format)) ++ push_event(stream->my_sink, gst_event_new_reconfigure()); ++ else ++ { ++ stream->current_format = stream->next_format; ++ stream->next_format.major_type = WG_MAJOR_TYPE_UNKNOWN; ++ pthread_cond_broadcast(&parser->stream_event_cond); ++ } ++ } + pthread_mutex_unlock(&parser->mutex); + pthread_cond_signal(&parser->init_cond); + break; +@@ -820,6 +864,14 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu + + pthread_mutex_lock(&parser->mutex); + ++ if (stream->next_format.major_type != WG_MAJOR_TYPE_UNKNOWN) ++ { ++ GST_DEBUG("Stream is changing format; discarding buffer."); ++ pthread_mutex_unlock(&parser->mutex); ++ gst_buffer_unref(buffer); ++ return GST_FLOW_OK; ++ } ++ + if (!stream->has_buffer) + { + stream->has_buffer = true; +@@ -923,7 +975,9 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) + gst_query_parse_caps(query, &filter); + + pthread_mutex_lock(&parser->mutex); +- if (stream->current_format.major_type != WG_MAJOR_TYPE_UNKNOWN) ++ if (stream->next_format.major_type != WG_MAJOR_TYPE_UNKNOWN) ++ caps = wg_format_to_caps(&stream->next_format); ++ else if (stream->current_format.major_type != WG_MAJOR_TYPE_UNKNOWN) + caps = wg_format_to_caps(&stream->current_format); + else + caps = get_supported_formats(); +@@ -959,7 +1013,8 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) + + pthread_mutex_lock(&parser->mutex); + +- if (stream->current_format.major_type == WG_MAJOR_TYPE_UNKNOWN) ++ if (stream->current_format.major_type == WG_MAJOR_TYPE_UNKNOWN || ++ stream->next_format.major_type != WG_MAJOR_TYPE_UNKNOWN) + { + pthread_mutex_unlock(&parser->mutex); + gst_query_set_accept_caps_result(query, TRUE); +@@ -969,6 +1024,8 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) + gst_query_parse_accept_caps(query, &caps); + wg_format_from_caps(&format, caps); + ret = wg_format_compare(&format, &stream->current_format); ++ if (!ret) ++ ret = wg_format_compare(&format, &stream->next_format); + + pthread_mutex_unlock(&parser->mutex); + +@@ -1003,6 +1060,7 @@ static struct wg_parser_stream *create_stream(struct wg_parser *parser, char *id + stream->number = parser->stream_count; + stream->no_more_pads = true; + stream->current_format.major_type = WG_MAJOR_TYPE_UNKNOWN; ++ stream->next_format.major_type = WG_MAJOR_TYPE_UNKNOWN; + + sprintf(pad_name, "qz_sink_%u", parser->stream_count); + stream->my_sink = gst_pad_new(pad_name, GST_PAD_SINK); +@@ -1660,6 +1718,7 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use + parser->error = true; + pthread_mutex_unlock(&parser->mutex); + pthread_cond_signal(&parser->init_cond); ++ pthread_cond_broadcast(&parser->stream_event_cond); + break; + + case GST_MESSAGE_WARNING: +@@ -1690,6 +1749,7 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use + GST_WARNING("Autoplugged element failed to initialise, trying again with protonvideoconvert."); + parser->error = true; + pthread_cond_signal(&parser->init_cond); ++ pthread_cond_broadcast(&parser->stream_event_cond); + } + pthread_mutex_unlock(&parser->mutex); + } +-- +2.46.0 + diff --git a/patches/wine-gst/0024-winegstreamer-Do-not-seek-live-sources.patch b/patches/wine-gst/0024-winegstreamer-Do-not-seek-live-sources.patch deleted file mode 100644 index ed369c50c..000000000 --- a/patches/wine-gst/0024-winegstreamer-Do-not-seek-live-sources.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 9e5e81aad59a6ae8335127396961e1121cd40592 Mon Sep 17 00:00:00 2001 -From: Torge Matthies -Date: Sun, 14 Apr 2024 06:12:55 +0200 -Subject: [PATCH 24/46] winegstreamer: Do not seek live sources. - -souphttpsrc seems to break from seeking sometimes: - - winegstreamer error: source: Server does not support seeking. - winegstreamer error: source: ../src-gst_good/ext/soup/gstsouphttpsrc.c(1948): gst_soup_http_src_do_request (): /GstBin:bin1/GstURIDecodeBin:uridecodebin1/GstSoupHTTPSrc:source: - Server does not accept Range HTTP header, URL: https://stream.vrcdn.live/live/djzombiepunk.live.ts, Redirect to: (NULL) - -Seeking a live source doesn't make sense anyway. ---- - dlls/winegstreamer/wg_parser.c | 29 +++++++++++++++++++++++------ - 1 file changed, 23 insertions(+), 6 deletions(-) - -diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 11b4d4f915a..20dae3e8cdd 100644 ---- a/dlls/winegstreamer/wg_parser.c -+++ b/dlls/winegstreamer/wg_parser.c -@@ -110,6 +110,8 @@ struct wg_parser - bool use_mediaconv; - bool use_opengl; - GstContext *context; -+ -+ bool is_live; - }; - static const unsigned int input_cache_chunk_size = 512 << 10; - -@@ -605,6 +607,9 @@ static NTSTATUS wg_parser_stream_seek(void *args) - - stream = get_stream(params->stream); - -+ if (stream->parser->is_live) -+ return S_OK; -+ - if (start_flags & AM_SEEKING_SeekToKeyFrame) - flags |= GST_SEEK_FLAG_KEY_UNIT; - if (start_flags & AM_SEEKING_Segment) -@@ -2065,9 +2070,9 @@ static NTSTATUS wg_parser_connect(void *args) - goto out; - - gst_element_set_base_time(parser->container, gst_clock_get_time(clock)); -- gst_element_set_state(parser->container, GST_STATE_PAUSED); -- ret = gst_element_get_state(parser->container, NULL, NULL, -1); -- -+ ret = gst_element_set_state(parser->container, GST_STATE_PAUSED); -+ if (ret == GST_STATE_CHANGE_ASYNC) -+ ret = gst_element_get_state(parser->container, NULL, NULL, -1); - if (ret == GST_STATE_CHANGE_FAILURE) - { - if (!parser->use_mediaconv && parser->init_gst == decodebin_parser_init_gst) -@@ -2079,13 +2084,19 @@ static NTSTATUS wg_parser_connect(void *args) - GST_ERROR("Failed to play stream."); - goto out; - } -+ else if (ret == GST_STATE_CHANGE_NO_PREROLL && parser->uri) -+ { -+ GST_DEBUG("Stream is live."); -+ parser->is_live = TRUE; -+ } - - pthread_mutex_lock(&parser->mutex); - - if (parser->uri) - { -- gst_element_set_state(parser->container, GST_STATE_PLAYING); -- ret = gst_element_get_state(parser->container, NULL, NULL, -1); -+ ret = gst_element_set_state(parser->container, GST_STATE_PLAYING); -+ if (ret == GST_STATE_CHANGE_ASYNC) -+ ret = gst_element_get_state(parser->container, NULL, NULL, -1); - if (ret == GST_STATE_CHANGE_FAILURE) - goto out; - } -@@ -2141,7 +2152,13 @@ static NTSTATUS wg_parser_connect(void *args) - } - if (gst_pad_peer_query_duration(stream->my_sink, GST_FORMAT_TIME, &duration)) - { -- stream->duration = duration == -1 ? (uint64_t)-1 : duration / 100; -+ if (duration == -1) -+ { -+ parser->is_live = TRUE; -+ stream->duration = (uint64_t)-1; -+ } -+ else -+ stream->duration = duration / 100; - break; - } - --- -2.46.0 - diff --git a/patches/wine-gst/0025-winegstreamer-Do-not-seek-live-sources.patch b/patches/wine-gst/0025-winegstreamer-Do-not-seek-live-sources.patch new file mode 100644 index 000000000..5fc8bf5e7 --- /dev/null +++ b/patches/wine-gst/0025-winegstreamer-Do-not-seek-live-sources.patch @@ -0,0 +1,223 @@ +From 0874bb1607a73e9b5e08a61e61b445165b2a65c5 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Sun, 14 Apr 2024 06:12:55 +0200 +Subject: [PATCH 25/49] winegstreamer: Do not seek live sources. + +souphttpsrc seems to break from seeking sometimes: + + winegstreamer error: source: Server does not support seeking. + winegstreamer error: source: ../src-gst_good/ext/soup/gstsouphttpsrc.c(1948): gst_soup_http_src_do_request (): /GstBin:bin1/GstURIDecodeBin:uridecodebin1/GstSoupHTTPSrc:source: + Server does not accept Range HTTP header, URL: https://stream.vrcdn.live/live/djzombiepunk.live.ts, Redirect to: (NULL) + +Seeking a live source doesn't make sense anyway. +--- + dlls/winegstreamer/gst_private.h | 2 ++ + dlls/winegstreamer/main.c | 13 ++++++++ + dlls/winegstreamer/media_source.c | 6 +++- + dlls/winegstreamer/unixlib.h | 8 +++++ + dlls/winegstreamer/wg_parser.c | 53 ++++++++++++++++++++++++++++++- + 5 files changed, 80 insertions(+), 2 deletions(-) + +diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h +index 88804c08a4c..fe3386c7def 100644 +--- a/dlls/winegstreamer/gst_private.h ++++ b/dlls/winegstreamer/gst_private.h +@@ -82,6 +82,8 @@ void wg_parser_push_data(wg_parser_t parser, const void *data, uint32_t size); + uint32_t wg_parser_get_stream_count(wg_parser_t parser); + wg_parser_stream_t wg_parser_get_stream(wg_parser_t parser, uint32_t index); + ++BOOL wg_parser_is_seekable(wg_parser_t parser); ++ + void wg_parser_stream_get_preferred_format(wg_parser_stream_t stream, struct wg_format *format); + void wg_parser_stream_get_codec_format(wg_parser_stream_t stream, struct wg_format *format); + void wg_parser_stream_enable(wg_parser_stream_t stream, const struct wg_format *format, +diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c +index f7733fcbcfb..3f1654542cf 100644 +--- a/dlls/winegstreamer/main.c ++++ b/dlls/winegstreamer/main.c +@@ -176,6 +176,19 @@ wg_parser_stream_t wg_parser_get_stream(wg_parser_t parser, uint32_t index) + return params.stream; + } + ++BOOL wg_parser_is_seekable(wg_parser_t parser) ++{ ++ struct wg_parser_is_seekable_params params = ++ { ++ .parser = parser, ++ }; ++ ++ TRACE("parser %#I64x.\n", parser); ++ ++ WINE_UNIX_CALL(unix_wg_parser_is_seekable, ¶ms); ++ return params.seekable; ++} ++ + void wg_parser_stream_get_preferred_format(wg_parser_stream_t stream, struct wg_format *format) + { + struct wg_parser_stream_get_preferred_format_params params = +diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c +index d0e9b6fdf71..6f9392d214a 100644 +--- a/dlls/winegstreamer/media_source.c ++++ b/dlls/winegstreamer/media_source.c +@@ -1465,7 +1465,11 @@ static HRESULT WINAPI media_source_GetCharacteristics(IMFMediaSource *iface, DWO + if (source->state == SOURCE_SHUTDOWN) + hr = MF_E_SHUTDOWN; + else +- *characteristics = MFMEDIASOURCE_CAN_SEEK | MFMEDIASOURCE_CAN_PAUSE; ++ { ++ *characteristics = MFMEDIASOURCE_CAN_PAUSE; ++ if (!source->wg_parser || wg_parser_is_seekable(source->wg_parser)) ++ *characteristics |= MFMEDIASOURCE_CAN_SEEK; ++ } + + LeaveCriticalSection(&source->cs); + +diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h +index 7fe6bc284d4..0dbcbff7f33 100644 +--- a/dlls/winegstreamer/unixlib.h ++++ b/dlls/winegstreamer/unixlib.h +@@ -244,6 +244,12 @@ struct wg_parser_get_stream_params + wg_parser_stream_t stream; + }; + ++struct wg_parser_is_seekable_params ++{ ++ wg_parser_t parser; ++ BOOL seekable; ++}; ++ + struct wg_parser_stream_get_preferred_format_params + { + wg_parser_stream_t stream; +@@ -486,6 +492,8 @@ enum unix_funcs + unix_wg_parser_get_stream_count, + unix_wg_parser_get_stream, + ++ unix_wg_parser_is_seekable, ++ + unix_wg_parser_stream_get_preferred_format, + unix_wg_parser_stream_get_codec_format, + unix_wg_parser_stream_enable, +diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c +index d6e42c3d815..2259ce08754 100644 +--- a/dlls/winegstreamer/wg_parser.c ++++ b/dlls/winegstreamer/wg_parser.c +@@ -110,6 +110,8 @@ struct wg_parser + bool use_mediaconv; + bool use_opengl; + GstContext *context; ++ ++ bool is_seekable; + }; + static const unsigned int input_cache_chunk_size = 512 << 10; + +@@ -169,6 +171,15 @@ static NTSTATUS wg_parser_get_stream(void *args) + return S_OK; + } + ++static NTSTATUS wg_parser_is_seekable(void *args) ++{ ++ struct wg_parser_is_seekable_params *params = args; ++ struct wg_parser *parser = get_parser(params->parser); ++ ++ params->seekable = parser->is_seekable; ++ return S_OK; ++} ++ + static NTSTATUS wg_parser_get_next_read_offset(void *args) + { + struct wg_parser_get_next_read_offset_params *params = args; +@@ -522,6 +533,9 @@ static NTSTATUS wg_parser_stream_seek(void *args) + + stream = get_stream(params->stream); + ++ if (!stream->parser->is_seekable) ++ return S_OK; ++ + if (start_flags & AM_SEEKING_SeekToKeyFrame) + flags |= GST_SEEK_FLAG_KEY_UNIT; + if (start_flags & AM_SEEKING_Segment) +@@ -1978,6 +1992,7 @@ static NTSTATUS wg_parser_connect(void *args) + parser->start_offset = parser->next_offset = parser->stop_offset = 0; + parser->next_pull_offset = 0; + parser->error = false; ++ parser->is_seekable = true; + + if (!parser->init_gst(parser)) + goto out; +@@ -1997,6 +2012,11 @@ static NTSTATUS wg_parser_connect(void *args) + GST_ERROR("Failed to play stream."); + goto out; + } ++ else if (ret == GST_STATE_CHANGE_NO_PREROLL && parser->uri) ++ { ++ GST_DEBUG("Stream does not preroll."); ++ parser->is_seekable = false; ++ } + + pthread_mutex_lock(&parser->mutex); + +@@ -2018,6 +2038,23 @@ static NTSTATUS wg_parser_connect(void *args) + goto out; + } + ++ if (parser->stream_count && parser->is_seekable) ++ { ++ GstQuery *query = gst_query_new_seeking(GST_FORMAT_TIME); ++ gboolean seekable = false; ++ ++ if (query && gst_pad_peer_query(parser->streams[0]->my_sink, query)) ++ { ++ gst_query_parse_seeking(query, NULL, &seekable, NULL, NULL); ++ gst_query_unref(query); ++ } ++ if (!seekable) ++ { ++ GST_DEBUG("Stream is not seekable."); ++ parser->is_seekable = false; ++ } ++ } ++ + for (i = 0; i < parser->stream_count; ++i) + { + struct wg_parser_stream *stream = parser->streams[i]; +@@ -2060,7 +2097,17 @@ static NTSTATUS wg_parser_connect(void *args) + } + if (gst_pad_peer_query_duration(stream->my_sink, GST_FORMAT_TIME, &duration)) + { +- stream->duration = duration == -1 ? (uint64_t)-1 : duration / 100; ++ if (duration == -1) ++ { ++ if (parser->uri) ++ { ++ GST_DEBUG("Stream has no duration."); ++ parser->is_seekable = false; ++ } ++ stream->duration = (uint64_t)-1; ++ } ++ else ++ stream->duration = duration / 100; + break; + } + +@@ -2378,6 +2425,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = + X(wg_parser_get_stream_count), + X(wg_parser_get_stream), + ++ X(wg_parser_is_seekable), ++ + X(wg_parser_stream_get_preferred_format), + X(wg_parser_stream_get_codec_format), + X(wg_parser_stream_enable), +@@ -2823,6 +2872,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = + X(wg_parser_get_stream_count), + X(wg_parser_get_stream), + ++ X(wg_parser_is_seekable), ++ + X64(wg_parser_stream_get_preferred_format), + X64(wg_parser_stream_get_codec_format), + X64(wg_parser_stream_enable), +-- +2.46.0 + diff --git a/patches/wine-gst/0025-winegstreamer-Implement-buffering-events.patch b/patches/wine-gst/0026-winegstreamer-Implement-buffering-events.patch similarity index 87% rename from patches/wine-gst/0025-winegstreamer-Implement-buffering-events.patch rename to patches/wine-gst/0026-winegstreamer-Implement-buffering-events.patch index f29e271d8..43f8ef48b 100644 --- a/patches/wine-gst/0025-winegstreamer-Implement-buffering-events.patch +++ b/patches/wine-gst/0026-winegstreamer-Implement-buffering-events.patch @@ -1,7 +1,7 @@ -From 07003f24e0ac6027b70c85c1498b366aabedb477 Mon Sep 17 00:00:00 2001 +From fc18f16912a564e10c57880d0df117f9a436cbb2 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 10 Apr 2024 15:11:02 +0200 -Subject: [PATCH 25/46] winegstreamer: Implement buffering events. +Subject: [PATCH 26/49] winegstreamer: Implement buffering events. --- dlls/winegstreamer/gst_private.h | 3 ++ @@ -12,7 +12,7 @@ Subject: [PATCH 25/46] winegstreamer: Implement buffering events. 5 files changed, 158 insertions(+) diff --git a/dlls/winegstreamer/gst_private.h b/dlls/winegstreamer/gst_private.h -index adefeaba15c..bdc59e1e347 100644 +index fe3386c7def..764ea3d2f03 100644 --- a/dlls/winegstreamer/gst_private.h +++ b/dlls/winegstreamer/gst_private.h @@ -79,6 +79,9 @@ void wg_parser_disconnect(wg_parser_t parser); @@ -26,10 +26,10 @@ index adefeaba15c..bdc59e1e347 100644 wg_parser_stream_t wg_parser_get_stream(wg_parser_t parser, uint32_t index); diff --git a/dlls/winegstreamer/main.c b/dlls/winegstreamer/main.c -index 374924a3e6a..fd1bf034a69 100644 +index 3f1654542cf..da11e3bc821 100644 --- a/dlls/winegstreamer/main.c +++ b/dlls/winegstreamer/main.c -@@ -230,6 +230,27 @@ bool wg_parser_get_next_read_offset(wg_parser_t parser, uint64_t *offset, uint32 +@@ -133,6 +133,27 @@ bool wg_parser_get_next_read_offset(wg_parser_t parser, uint64_t *offset, uint32 return true; } @@ -58,7 +58,7 @@ index 374924a3e6a..fd1bf034a69 100644 { struct wg_parser_push_data_params params = diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index ce6de32d1c4..4f3c5d101f0 100644 +index 6f9392d214a..b9054f48ccf 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -207,6 +207,9 @@ struct media_source @@ -71,7 +71,7 @@ index ce6de32d1c4..4f3c5d101f0 100644 }; static inline struct media_stream *impl_from_IMFMediaStream(IMFMediaStream *iface) -@@ -696,6 +699,7 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) +@@ -825,6 +828,7 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) stream->busy = TRUE; LeaveCriticalSection(&source->cs); @@ -79,7 +79,7 @@ index ce6de32d1c4..4f3c5d101f0 100644 ret = wg_parser_stream_get_buffer(source->wg_parser, stream->wg_stream, &buffer); EnterCriticalSection(&source->cs); stream->busy = FALSE; -@@ -832,6 +836,41 @@ static DWORD CALLBACK read_thread(void *arg) +@@ -961,6 +965,41 @@ static DWORD CALLBACK read_thread(void *arg) return 0; } @@ -121,7 +121,7 @@ index ce6de32d1c4..4f3c5d101f0 100644 static HRESULT WINAPI media_stream_QueryInterface(IMFMediaStream *iface, REFIID riid, void **out) { struct media_stream *stream = impl_from_IMFMediaStream(iface); -@@ -1504,6 +1543,13 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) +@@ -1632,6 +1671,13 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) wg_parser_disconnect(source->wg_parser); @@ -135,7 +135,7 @@ index ce6de32d1c4..4f3c5d101f0 100644 if (source->read_thread) { source->read_thread_shutdown = true; -@@ -1607,6 +1653,8 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc +@@ -1735,6 +1781,8 @@ static HRESULT media_source_create(struct object_context *context, IMFMediaSourc if (context->type != WG_PARSER_URIDECODEBIN) object->read_thread = CreateThread(NULL, 0, read_thread, object, 0, NULL); @@ -144,7 +144,7 @@ index ce6de32d1c4..4f3c5d101f0 100644 object->state = SOURCE_OPENING; if (FAILED(hr = wg_parser_connect(parser, object->file_size, context->url))) -@@ -1689,6 +1737,12 @@ fail: +@@ -1819,6 +1867,12 @@ fail: if (stream_count != UINT_MAX) wg_parser_disconnect(object->wg_parser); @@ -158,10 +158,10 @@ index ce6de32d1c4..4f3c5d101f0 100644 { object->read_thread_shutdown = true; diff --git a/dlls/winegstreamer/unixlib.h b/dlls/winegstreamer/unixlib.h -index f9b87e51b93..f4b33557d1a 100644 +index 0dbcbff7f33..c099ed255ee 100644 --- a/dlls/winegstreamer/unixlib.h +++ b/dlls/winegstreamer/unixlib.h -@@ -257,6 +257,16 @@ struct wg_parser_push_data_params +@@ -231,6 +231,16 @@ struct wg_parser_push_data_params UINT32 size; }; @@ -178,7 +178,7 @@ index f9b87e51b93..f4b33557d1a 100644 struct wg_parser_get_stream_count_params { wg_parser_t parser; -@@ -524,6 +534,8 @@ enum unix_funcs +@@ -489,6 +499,8 @@ enum unix_funcs unix_wg_parser_get_next_read_offset, unix_wg_parser_push_data, @@ -188,7 +188,7 @@ index f9b87e51b93..f4b33557d1a 100644 unix_wg_parser_get_stream, diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 20dae3e8cdd..59ff8495e09 100644 +index 2259ce08754..c6129d49ed5 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c @@ -43,6 +43,12 @@ @@ -207,14 +207,14 @@ index 20dae3e8cdd..59ff8495e09 100644 @@ -112,6 +118,9 @@ struct wg_parser GstContext *context; - bool is_live; + bool is_seekable; + + bool buffering; + bool sent_buffering_event; }; static const unsigned int input_cache_chunk_size = 512 << 10; -@@ -244,6 +253,47 @@ static NTSTATUS wg_parser_push_data(void *args) +@@ -246,6 +255,47 @@ static NTSTATUS wg_parser_push_data(void *args) return S_OK; } @@ -259,10 +259,10 @@ index 20dae3e8cdd..59ff8495e09 100644 + return hr; +} + - static NTSTATUS wg_parser_stream_get_current_format(void *args) + static NTSTATUS wg_parser_stream_get_preferred_format(void *args) { - const struct wg_parser_stream_get_current_format_params *params = args; -@@ -1860,6 +1910,19 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use + const struct wg_parser_stream_get_preferred_format_params *params = args; +@@ -1787,6 +1837,19 @@ static GstBusSyncReply bus_handler_cb(GstBus *bus, GstMessage *msg, gpointer use break; } @@ -282,7 +282,7 @@ index 20dae3e8cdd..59ff8495e09 100644 default: break; } -@@ -2260,6 +2323,7 @@ static NTSTATUS wg_parser_disconnect(void *args) +@@ -2209,6 +2272,7 @@ static NTSTATUS wg_parser_disconnect(void *args) parser->sink_connected = false; pthread_mutex_unlock(&parser->mutex); pthread_cond_signal(&parser->read_cond); @@ -290,7 +290,7 @@ index 20dae3e8cdd..59ff8495e09 100644 for (i = 0; i < parser->stream_count; ++i) free_stream(parser->streams[i]); -@@ -2474,6 +2538,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = +@@ -2422,6 +2486,8 @@ const unixlib_entry_t __wine_unix_call_funcs[] = X(wg_parser_get_next_read_offset), X(wg_parser_push_data), @@ -299,7 +299,7 @@ index 20dae3e8cdd..59ff8495e09 100644 X(wg_parser_get_stream_count), X(wg_parser_get_stream), -@@ -3040,6 +3106,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = +@@ -2869,6 +2935,8 @@ const unixlib_entry_t __wine_unix_call_wow64_funcs[] = X(wg_parser_get_next_read_offset), X64(wg_parser_push_data), diff --git a/patches/wine-gst/0026-mf-Send-sample-requests-for-unused-space-of-sample-q.patch b/patches/wine-gst/0027-mf-samplegrabber-Send-sample-requests-for-unused-spa.patch similarity index 95% rename from patches/wine-gst/0026-mf-Send-sample-requests-for-unused-space-of-sample-q.patch rename to patches/wine-gst/0027-mf-samplegrabber-Send-sample-requests-for-unused-spa.patch index 5fff9086d..8fd59060c 100644 --- a/patches/wine-gst/0026-mf-Send-sample-requests-for-unused-space-of-sample-q.patch +++ b/patches/wine-gst/0027-mf-samplegrabber-Send-sample-requests-for-unused-spa.patch @@ -1,8 +1,8 @@ -From 071a24a7f5ce8499578602755f976ab169ebaeaf Mon Sep 17 00:00:00 2001 +From f4d59ae9cc3de7105919c862757c17eafd90b3fd Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Tue, 21 May 2024 08:25:47 +0200 -Subject: [PATCH 26/46] mf: Send sample requests for unused space of sample - queue on pause => restart. +Subject: [PATCH 27/49] mf/samplegrabber: Send sample requests for unused space + of sample queue on pause => restart. --- dlls/mf/samplegrabber.c | 27 ++++++++++++++------------- diff --git a/patches/wine-gst/0027-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch b/patches/wine-gst/0028-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch similarity index 76% rename from patches/wine-gst/0027-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch rename to patches/wine-gst/0028-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch index 7c7606668..f4917187f 100644 --- a/patches/wine-gst/0027-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch +++ b/patches/wine-gst/0028-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch @@ -1,7 +1,7 @@ -From 020c5e87fbd73478f9d54c5cd1ad74639f680d6b Mon Sep 17 00:00:00 2001 +From 14b19a277f337874bec0205b90f2611f9f3fabd1 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 3 Jun 2024 11:05:38 +0200 -Subject: [PATCH 27/46] winegstreamer: Fix race between +Subject: [PATCH 28/49] winegstreamer: Fix race between wg_parser_stream_disable and GST_EVENT_FLUSH_STOP. --- @@ -9,10 +9,10 @@ Subject: [PATCH 27/46] winegstreamer: Fix race between 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 59ff8495e09..280d1e52528 100644 +index c6129d49ed5..b5acba93fdd 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -985,8 +985,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -874,8 +874,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) pthread_mutex_lock(&parser->mutex); stream->eos = false; diff --git a/patches/wine-gst/0028-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch b/patches/wine-gst/0029-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch similarity index 83% rename from patches/wine-gst/0028-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch rename to patches/wine-gst/0029-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch index 40c610280..7cef55bcc 100644 --- a/patches/wine-gst/0028-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch +++ b/patches/wine-gst/0029-winegstreamer-Handle-Gstreamer-pipeline-flushes-grac.patch @@ -1,7 +1,7 @@ -From 1a45cb802ded34863790a91aaffa32e64bb419de Mon Sep 17 00:00:00 2001 +From 20d5d0ab5f9678f88842c2c8f98d6f2148089d35 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 14 Jun 2024 03:11:44 +0200 -Subject: [PATCH 28/46] winegstreamer: Handle Gstreamer pipeline flushes +Subject: [PATCH 29/49] winegstreamer: Handle Gstreamer pipeline flushes gracefully. If a GST_EVENT_FLUSH_START event is received between the calls from PE code to wg_parser_stream_get_buffer @@ -14,10 +14,10 @@ If wg_parser_stream_copy_buffer returns an error, retry the whole wait_on_sample 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 4f3c5d101f0..b3e0c77eade 100644 +index b9054f48ccf..5030838bf2c 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -635,6 +635,7 @@ static HRESULT media_stream_send_sample(struct media_stream *stream, const struc +@@ -764,6 +764,7 @@ static HRESULT media_stream_send_sample(struct media_stream *stream, const struc if (!wg_parser_stream_copy_buffer(stream->wg_stream, data, 0, wg_buffer->size)) { @@ -25,7 +25,7 @@ index 4f3c5d101f0..b3e0c77eade 100644 wg_parser_stream_release_buffer(stream->wg_stream); IMFMediaBuffer_Unlock(buffer); goto out; -@@ -693,10 +694,10 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) +@@ -822,10 +823,10 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) { struct media_source *source = impl_from_IMFMediaSource(stream->media_source); struct wg_parser_buffer buffer; @@ -38,7 +38,7 @@ index 4f3c5d101f0..b3e0c77eade 100644 stream->busy = TRUE; LeaveCriticalSection(&source->cs); memset(&buffer, 0, sizeof(buffer)); -@@ -712,7 +713,12 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) +@@ -841,7 +842,12 @@ static HRESULT wait_on_sample(struct media_stream *stream, IUnknown *token) } if (ret) diff --git a/patches/wine-gst/0029-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch b/patches/wine-gst/0030-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch similarity index 92% rename from patches/wine-gst/0029-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch rename to patches/wine-gst/0030-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch index 150595af9..78d5fc79b 100644 --- a/patches/wine-gst/0029-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch +++ b/patches/wine-gst/0030-winegstreamer-Do-waits-for-samples-on-stream-specifi.patch @@ -1,7 +1,7 @@ -From ed22e513ddc2b7d5059d3fd5d584376a50120057 Mon Sep 17 00:00:00 2001 +From c87cdc5bca26ea3aac4fc520eae4deb02413f30f Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 14 Jun 2024 03:08:48 +0200 -Subject: [PATCH 29/46] winegstreamer: Do waits for samples on stream-specific +Subject: [PATCH 30/49] winegstreamer: Do waits for samples on stream-specific work queues. --- @@ -10,7 +10,7 @@ Subject: [PATCH 29/46] winegstreamer: Do waits for samples on stream-specific 2 files changed, 296 insertions(+), 64 deletions(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index b3e0c77eade..1d989b7f21a 100644 +index 5030838bf2c..4dd6db8c9f5 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c @@ -121,9 +121,29 @@ static HRESULT object_context_create(DWORD flags, IMFByteStream *stream, const W @@ -172,7 +172,7 @@ index b3e0c77eade..1d989b7f21a 100644 source_async_command_AddRef, source_async_command_Release, }; -@@ -435,7 +502,6 @@ static BOOL enqueue_token(struct media_stream *stream, IUnknown *token) +@@ -568,7 +635,6 @@ static BOOL enqueue_token(struct media_stream *stream, IUnknown *token) static void flush_token_queue(struct media_stream *stream, BOOL send) { @@ -180,7 +180,7 @@ index b3e0c77eade..1d989b7f21a 100644 LONG i; for (i = 0; i < stream->token_queue_count; i++) -@@ -445,13 +511,12 @@ static void flush_token_queue(struct media_stream *stream, BOOL send) +@@ -578,13 +644,12 @@ static void flush_token_queue(struct media_stream *stream, BOOL send) IUnknown *op; HRESULT hr; @@ -197,7 +197,7 @@ index b3e0c77eade..1d989b7f21a 100644 IUnknown_Release(op); } if (FAILED(hr)) -@@ -755,15 +820,6 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA +@@ -884,15 +949,6 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA if (FAILED(hr = media_source_stop(source))) WARN("Failed to stop source %p, hr %#lx\n", source, hr); break; @@ -213,7 +213,7 @@ index b3e0c77eade..1d989b7f21a 100644 } LeaveCriticalSection(&source->cs); -@@ -782,6 +838,61 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = +@@ -911,6 +967,61 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = source_async_commands_Invoke, }; @@ -275,7 +275,7 @@ index b3e0c77eade..1d989b7f21a 100644 static DWORD CALLBACK read_thread(void *arg) { struct media_source *source = arg; -@@ -1029,15 +1140,14 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown +@@ -1158,15 +1269,14 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown hr = MF_E_MEDIA_SOURCE_WRONGSTATE; else if (stream->eos) hr = MF_E_END_OF_STREAM; @@ -294,7 +294,7 @@ index b3e0c77eade..1d989b7f21a 100644 IUnknown_Release(op); } -@@ -1072,9 +1182,11 @@ static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor * +@@ -1201,9 +1311,11 @@ static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor * return E_OUTOFMEMORY; object->IMFMediaStream_iface.lpVtbl = &media_stream_vtbl; @@ -307,7 +307,7 @@ index b3e0c77eade..1d989b7f21a 100644 { free(object); return hr; -@@ -1571,6 +1683,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) +@@ -1699,6 +1811,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) struct media_stream *stream = source->streams[source->stream_count]; IMFStreamDescriptor_Release(source->descriptors[source->stream_count]); IMFMediaEventQueue_Shutdown(stream->event_queue); @@ -315,7 +315,7 @@ index b3e0c77eade..1d989b7f21a 100644 IMFMediaStream_Release(&stream->IMFMediaStream_iface); } free(source->descriptors); -@@ -1731,7 +1844,11 @@ fail: +@@ -1861,7 +1974,11 @@ fail: for (i = 0; i < stream_count; i++) { if (object->streams && object->streams[i]) @@ -328,11 +328,11 @@ index b3e0c77eade..1d989b7f21a 100644 for (i = 0; i < stream_count; i++) { diff --git a/dlls/winegstreamer/new_media_source.c b/dlls/winegstreamer/new_media_source.c -index a97d659e58d..06482fd36dc 100644 +index efaf6a3e087..7444fc1c788 100644 --- a/dlls/winegstreamer/new_media_source.c +++ b/dlls/winegstreamer/new_media_source.c -@@ -153,15 +153,37 @@ static HRESULT object_context_create(DWORD flags, IMFByteStream *stream, const W - return S_OK; +@@ -239,15 +239,37 @@ static HRESULT create_media_source_fallback(struct object_context *context, IUnk + return hr; } +enum stream_async_op @@ -369,7 +369,7 @@ index a97d659e58d..06482fd36dc 100644 IUnknown **token_queue; LONG token_queue_count; LONG token_queue_cap; -@@ -175,7 +197,6 @@ enum source_async_op +@@ -261,7 +283,6 @@ enum source_async_op SOURCE_ASYNC_START, SOURCE_ASYNC_PAUSE, SOURCE_ASYNC_STOP, @@ -377,7 +377,7 @@ index a97d659e58d..06482fd36dc 100644 }; struct source_async_command -@@ -191,11 +212,6 @@ struct source_async_command +@@ -277,11 +298,6 @@ struct source_async_command GUID format; PROPVARIANT position; } start; @@ -389,7 +389,7 @@ index a97d659e58d..06482fd36dc 100644 } u; }; -@@ -240,6 +256,16 @@ static inline struct media_stream *impl_from_IMFMediaStream(IMFMediaStream *ifac +@@ -326,6 +342,16 @@ static inline struct media_stream *impl_from_IMFMediaStream(IMFMediaStream *ifac return CONTAINING_RECORD(iface, struct media_stream, IMFMediaStream_iface); } @@ -406,7 +406,7 @@ index a97d659e58d..06482fd36dc 100644 static inline struct media_source *impl_from_IMFMediaSource(IMFMediaSource *iface) { return CONTAINING_RECORD(iface, struct media_source, IMFMediaSource_iface); -@@ -270,7 +296,7 @@ static inline struct source_async_command *impl_from_async_command_IUnknown(IUnk +@@ -356,7 +382,7 @@ static inline struct source_async_command *impl_from_async_command_IUnknown(IUnk return CONTAINING_RECORD(iface, struct source_async_command, IUnknown_iface); } @@ -415,7 +415,7 @@ index a97d659e58d..06482fd36dc 100644 { if (IsEqualIID(riid, &IID_IUnknown)) { -@@ -284,6 +310,52 @@ static HRESULT WINAPI source_async_command_QueryInterface(IUnknown *iface, REFII +@@ -370,6 +396,52 @@ static HRESULT WINAPI source_async_command_QueryInterface(IUnknown *iface, REFII return E_NOINTERFACE; } @@ -468,7 +468,7 @@ index a97d659e58d..06482fd36dc 100644 static ULONG WINAPI source_async_command_AddRef(IUnknown *iface) { struct source_async_command *command = impl_from_async_command_IUnknown(iface); -@@ -302,11 +374,6 @@ static ULONG WINAPI source_async_command_Release(IUnknown *iface) +@@ -388,11 +460,6 @@ static ULONG WINAPI source_async_command_Release(IUnknown *iface) IMFPresentationDescriptor_Release(command->u.start.descriptor); PropVariantClear(&command->u.start.position); } @@ -480,7 +480,7 @@ index a97d659e58d..06482fd36dc 100644 free(command); } -@@ -315,7 +382,7 @@ static ULONG WINAPI source_async_command_Release(IUnknown *iface) +@@ -401,7 +468,7 @@ static ULONG WINAPI source_async_command_Release(IUnknown *iface) static const IUnknownVtbl source_async_command_vtbl = { @@ -489,7 +489,7 @@ index a97d659e58d..06482fd36dc 100644 source_async_command_AddRef, source_async_command_Release, }; -@@ -452,7 +519,6 @@ static BOOL enqueue_token(struct media_stream *stream, IUnknown *token) +@@ -568,7 +635,6 @@ static BOOL enqueue_token(struct media_stream *stream, IUnknown *token) static void flush_token_queue(struct media_stream *stream, BOOL send) { @@ -497,7 +497,7 @@ index a97d659e58d..06482fd36dc 100644 LONG i; for (i = 0; i < stream->token_queue_count; i++) -@@ -462,13 +528,12 @@ static void flush_token_queue(struct media_stream *stream, BOOL send) +@@ -578,13 +644,12 @@ static void flush_token_queue(struct media_stream *stream, BOOL send) IUnknown *op; HRESULT hr; @@ -514,7 +514,7 @@ index a97d659e58d..06482fd36dc 100644 IUnknown_Release(op); } if (FAILED(hr)) -@@ -734,15 +799,6 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA +@@ -844,15 +909,6 @@ static HRESULT WINAPI source_async_commands_Invoke(IMFAsyncCallback *iface, IMFA if (FAILED(hr = media_source_stop(source))) WARN("Failed to stop source %p, hr %#lx\n", source, hr); break; @@ -530,7 +530,7 @@ index a97d659e58d..06482fd36dc 100644 } LeaveCriticalSection(&source->cs); -@@ -761,6 +817,61 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = +@@ -871,6 +927,61 @@ static const IMFAsyncCallbackVtbl source_async_commands_callback_vtbl = source_async_commands_Invoke, }; @@ -592,7 +592,7 @@ index a97d659e58d..06482fd36dc 100644 static HRESULT WINAPI media_stream_QueryInterface(IMFMediaStream *iface, REFIID riid, void **out) { struct media_stream *stream = impl_from_IMFMediaStream(iface); -@@ -913,15 +1024,14 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown +@@ -1023,15 +1134,14 @@ static HRESULT WINAPI media_stream_RequestSample(IMFMediaStream *iface, IUnknown hr = MF_E_MEDIA_SOURCE_WRONGSTATE; else if (stream->eos) hr = MF_E_END_OF_STREAM; @@ -611,7 +611,7 @@ index a97d659e58d..06482fd36dc 100644 IUnknown_Release(op); } -@@ -955,9 +1065,11 @@ static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor * +@@ -1065,9 +1175,11 @@ static HRESULT media_stream_create(IMFMediaSource *source, IMFStreamDescriptor * return E_OUTOFMEMORY; object->IMFMediaStream_iface.lpVtbl = &media_stream_vtbl; @@ -624,7 +624,7 @@ index a97d659e58d..06482fd36dc 100644 { free(object); return hr; -@@ -1407,6 +1519,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) +@@ -1517,6 +1629,7 @@ static HRESULT WINAPI media_source_Shutdown(IMFMediaSource *iface) struct media_stream *stream = source->streams[source->stream_count]; IMFStreamDescriptor_Release(source->descriptors[source->stream_count]); IMFMediaEventQueue_Shutdown(stream->event_queue); @@ -632,7 +632,7 @@ index a97d659e58d..06482fd36dc 100644 IMFMediaStream_Release(&stream->IMFMediaStream_iface); } free(source->stream_map); -@@ -1640,6 +1753,8 @@ fail: +@@ -1731,6 +1844,8 @@ fail: { struct media_stream *stream = object->streams[object->stream_count]; IMFStreamDescriptor_Release(object->descriptors[object->stream_count]); diff --git a/patches/wine-gst/0030-mf-session-Ensure-that-the-command-callback-does-not.patch b/patches/wine-gst/0031-mf-session-Ensure-that-the-command-callback-does-not.patch similarity index 85% rename from patches/wine-gst/0030-mf-session-Ensure-that-the-command-callback-does-not.patch rename to patches/wine-gst/0031-mf-session-Ensure-that-the-command-callback-does-not.patch index c9e8a554c..411e8d8f1 100644 --- a/patches/wine-gst/0030-mf-session-Ensure-that-the-command-callback-does-not.patch +++ b/patches/wine-gst/0031-mf-session-Ensure-that-the-command-callback-does-not.patch @@ -1,7 +1,7 @@ -From 6543277fe80dd81f5213b98f16efe8154d1e7570 Mon Sep 17 00:00:00 2001 +From 05dcbdb7e95a3e2d8a9e16eb5712fd2743eedd7e Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 8 Jul 2024 10:30:50 +0200 -Subject: [PATCH 30/46] mf/session: Ensure that the command callback does not +Subject: [PATCH 31/49] mf/session: Ensure that the command callback does not return without clearing SESSION_FLAG_PENDING_COMMAND. Leaving SESSION_FLAG_PENDING_COMMAND set results in no more work items being queued by session_submit_command, and even @@ -16,10 +16,10 @@ Fix this by ensuring that SESSION_FLAG_PENDING_COMMAND is always cleared before 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c -index a5caad3c97a..752bdcf1c21 100644 +index 3f3be2b84b0..d43cede7874 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c -@@ -2744,7 +2744,6 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, +@@ -2645,7 +2645,6 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, break; case SESSION_CMD_SET_TOPOLOGY: session_set_topology(session, op->set_topology.flags, op->set_topology.topology); @@ -27,7 +27,7 @@ index a5caad3c97a..752bdcf1c21 100644 break; case SESSION_CMD_START: session_start(session, &op->start.time_format, &op->start.start_position); -@@ -2767,12 +2766,14 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, +@@ -2668,12 +2667,14 @@ static HRESULT WINAPI session_commands_callback_Invoke(IMFAsyncCallback *iface, break; case SESSION_CMD_SHUTDOWN: session_clear_command_list(session); diff --git a/patches/wine-gst/0031-mf-session-Prevent-media-session-from-running-comman.patch b/patches/wine-gst/0032-mf-session-Prevent-media-session-from-running-comman.patch similarity index 87% rename from patches/wine-gst/0031-mf-session-Prevent-media-session-from-running-comman.patch rename to patches/wine-gst/0032-mf-session-Prevent-media-session-from-running-comman.patch index 5cd6dff19..10ee2bd14 100644 --- a/patches/wine-gst/0031-mf-session-Prevent-media-session-from-running-comman.patch +++ b/patches/wine-gst/0032-mf-session-Prevent-media-session-from-running-comman.patch @@ -1,7 +1,7 @@ -From 53391fb4b036831f7aeac81a46946a4769a445d6 Mon Sep 17 00:00:00 2001 +From 5889f10d8679bf7c0d0d5492f72ef016f5144e49 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 29 Jul 2024 04:21:03 +0200 -Subject: [PATCH 31/46] mf/session: Prevent media session from running commands +Subject: [PATCH 32/49] mf/session: Prevent media session from running commands concurrently. --- @@ -9,10 +9,10 @@ Subject: [PATCH 31/46] mf/session: Prevent media session from running commands 1 file changed, 64 insertions(+), 41 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c -index 752bdcf1c21..e119755f732 100644 +index d43cede7874..170a31ef2ad 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c -@@ -220,6 +220,7 @@ enum presentation_flags +@@ -219,6 +219,7 @@ enum presentation_flags SESSION_FLAG_END_OF_PRESENTATION = 0x10, SESSION_FLAG_PENDING_RATE_CHANGE = 0x20, SESSION_FLAG_PENDING_COMMAND = 0x40, @@ -20,7 +20,7 @@ index 752bdcf1c21..e119755f732 100644 }; struct media_session -@@ -455,6 +456,33 @@ static HRESULT session_is_shut_down(struct media_session *session) +@@ -454,6 +455,33 @@ static HRESULT session_is_shut_down(struct media_session *session) return session->state == SESSION_STATE_SHUT_DOWN ? MF_E_SHUTDOWN : S_OK; } @@ -54,7 +54,7 @@ index 752bdcf1c21..e119755f732 100644 static HRESULT session_submit_command(struct media_session *session, struct session_op *op) { HRESULT hr; -@@ -464,13 +492,12 @@ static HRESULT session_submit_command(struct media_session *session, struct sess +@@ -463,13 +491,12 @@ static HRESULT session_submit_command(struct media_session *session, struct sess EnterCriticalSection(&session->cs); if (SUCCEEDED(hr = session_is_shut_down(session))) { @@ -69,7 +69,7 @@ index 752bdcf1c21..e119755f732 100644 } LeaveCriticalSection(&session->cs); -@@ -953,17 +980,9 @@ static struct topo_node *session_get_topo_node_output(const struct media_session +@@ -871,17 +898,9 @@ static struct topo_node *session_get_node_by_id(const struct media_session *sess static void session_command_complete(struct media_session *session) { @@ -89,7 +89,7 @@ index 752bdcf1c21..e119755f732 100644 } static void session_command_complete_with_event(struct media_session *session, MediaEventType event, -@@ -995,21 +1014,11 @@ static HRESULT session_subscribe_sources(struct media_session *session) +@@ -913,21 +932,11 @@ static HRESULT session_subscribe_sources(struct media_session *session) return hr; } @@ -115,7 +115,7 @@ index 752bdcf1c21..e119755f732 100644 } static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position) -@@ -1034,6 +1043,9 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -952,6 +961,9 @@ static void session_start(struct media_session *session, const GUID *time_format /* fallthrough */ case SESSION_STATE_PAUSED: case SESSION_STATE_STARTED: @@ -125,7 +125,7 @@ index 752bdcf1c21..e119755f732 100644 if (session->state == SESSION_STATE_STARTED && !(session->caps & MFSESSIONCAP_SEEK)) { WARN("Seeking is not supported for this session.\n"); -@@ -1067,6 +1079,12 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -985,6 +997,12 @@ static void session_start(struct media_session *session, const GUID *time_format session_command_complete_with_event(session, MESessionStarted, hr, NULL); return; } @@ -138,7 +138,7 @@ index 752bdcf1c21..e119755f732 100644 } LIST_FOR_EACH_ENTRY(topo_node, &session->presentation.nodes, struct topo_node, entry) -@@ -1079,6 +1097,11 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -997,6 +1015,11 @@ static void session_start(struct media_session *session, const GUID *time_format stream->draining = FALSE; } } @@ -150,7 +150,7 @@ index 752bdcf1c21..e119755f732 100644 } if (session->state == SESSION_STATE_STARTED) -@@ -1092,11 +1115,11 @@ static void session_start(struct media_session *session, const GUID *time_format +@@ -1010,11 +1033,11 @@ static void session_start(struct media_session *session, const GUID *time_format else if (node->type == MF_TOPOLOGY_TRANSFORM_NODE) IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_COMMAND_FLUSH, 0); } @@ -165,7 +165,7 @@ index 752bdcf1c21..e119755f732 100644 default: session_command_complete_with_event(session, MESessionStarted, MF_E_INVALIDREQUEST, NULL); break; -@@ -1110,7 +1133,7 @@ static void session_set_started(struct media_session *session) +@@ -1028,7 +1051,7 @@ static void session_set_started(struct media_session *session) unsigned int caps; DWORD flags; @@ -174,7 +174,7 @@ index 752bdcf1c21..e119755f732 100644 caps = session->caps | MFSESSIONCAP_PAUSE; -@@ -1142,7 +1165,7 @@ static void session_set_paused(struct media_session *session, unsigned int state +@@ -1060,7 +1083,7 @@ static void session_set_paused(struct media_session *session, unsigned int state /* Failed event status could indicate a failure during normal transition to paused state, or an attempt to pause from invalid initial state. To finalize failed transition in the former case, state is still forced to PAUSED, otherwise previous state is retained. */ @@ -183,7 +183,7 @@ index 752bdcf1c21..e119755f732 100644 if (SUCCEEDED(status)) session_set_caps(session, session->caps & ~MFSESSIONCAP_PAUSE); session_command_complete_with_event(session, MESessionPaused, status, NULL); -@@ -1150,7 +1173,7 @@ static void session_set_paused(struct media_session *session, unsigned int state +@@ -1068,7 +1091,7 @@ static void session_set_paused(struct media_session *session, unsigned int state static void session_set_closed(struct media_session *session, HRESULT status) { @@ -192,7 +192,7 @@ index 752bdcf1c21..e119755f732 100644 if (SUCCEEDED(status)) session_set_caps(session, session->caps & ~(MFSESSIONCAP_START | MFSESSIONCAP_SEEK)); session_command_complete_with_event(session, MESessionClosed, status, NULL); -@@ -1167,7 +1190,7 @@ static void session_pause(struct media_session *session) +@@ -1085,7 +1108,7 @@ static void session_pause(struct media_session *session) /* Transition in two steps - pause the clock, wait for sinks, then pause sources. */ if (SUCCEEDED(hr = IMFPresentationClock_Pause(session->clock))) @@ -201,7 +201,7 @@ index 752bdcf1c21..e119755f732 100644 state = SESSION_STATE_PAUSED; break; -@@ -1205,7 +1228,7 @@ static void session_set_stopped(struct media_session *session, HRESULT status) +@@ -1123,7 +1146,7 @@ static void session_set_stopped(struct media_session *session, HRESULT status) MediaEventType event_type; IMFMediaEvent *event; @@ -210,7 +210,7 @@ index 752bdcf1c21..e119755f732 100644 event_type = session->presentation.flags & SESSION_FLAG_END_OF_PRESENTATION ? MESessionEnded : MESessionStopped; if (SUCCEEDED(MFCreateMediaEvent(event_type, &GUID_NULL, status, NULL, &event))) -@@ -1230,7 +1253,7 @@ static void session_stop(struct media_session *session) +@@ -1148,7 +1171,7 @@ static void session_stop(struct media_session *session) /* Transition in two steps - stop the clock, wait for sinks, then stop sources. */ IMFPresentationClock_GetTime(session->clock, &session->presentation.clock_stop_time); if (SUCCEEDED(hr = IMFPresentationClock_Stop(session->clock))) @@ -219,7 +219,7 @@ index 752bdcf1c21..e119755f732 100644 else session_set_stopped(session, hr); -@@ -1252,7 +1275,7 @@ static HRESULT session_finalize_sinks(struct media_session *session) +@@ -1170,7 +1193,7 @@ static HRESULT session_finalize_sinks(struct media_session *session) HRESULT hr = S_OK; session->presentation.flags &= ~SESSION_FLAG_FINALIZE_SINKS; @@ -228,7 +228,7 @@ index 752bdcf1c21..e119755f732 100644 LIST_FOR_EACH_ENTRY(sink, &session->presentation.sinks, struct media_sink, entry) { -@@ -1288,7 +1311,7 @@ static void session_close(struct media_session *session) +@@ -1206,7 +1229,7 @@ static void session_close(struct media_session *session) case SESSION_STATE_PAUSED: session->presentation.flags |= SESSION_FLAG_FINALIZE_SINKS; if (SUCCEEDED(hr = IMFPresentationClock_Stop(session->clock))) @@ -237,7 +237,7 @@ index 752bdcf1c21..e119755f732 100644 break; default: hr = MF_E_INVALIDREQUEST; -@@ -2402,7 +2425,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) +@@ -2303,7 +2326,7 @@ static HRESULT WINAPI mfsession_Shutdown(IMFMediaSession *iface) EnterCriticalSection(&session->cs); if (SUCCEEDED(hr = session_is_shut_down(session))) { @@ -246,7 +246,7 @@ index 752bdcf1c21..e119755f732 100644 IMFMediaEventQueue_Shutdown(session->event_queue); if (session->quality_manager) IMFQualityManager_Shutdown(session->quality_manager); -@@ -3117,10 +3140,10 @@ static void session_set_source_object_state(struct media_session *session, IUnkn +@@ -3020,10 +3043,10 @@ static void session_set_source_object_state(struct media_session *session, IUnkn } } } @@ -259,7 +259,7 @@ index 752bdcf1c21..e119755f732 100644 break; case SESSION_STATE_PAUSING_SOURCES: -@@ -3182,7 +3205,7 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre +@@ -3085,7 +3108,7 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre break; if (SUCCEEDED(session_start_clock(session))) diff --git a/patches/wine-gst/0032-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch b/patches/wine-gst/0033-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch similarity index 86% rename from patches/wine-gst/0032-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch rename to patches/wine-gst/0033-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch index 8fdfa7226..462a30426 100644 --- a/patches/wine-gst/0032-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch +++ b/patches/wine-gst/0033-mf-sar-Allow-starting-audio-renderer-again-after-pau.patch @@ -1,7 +1,7 @@ -From 2f19878dd2d52c52e97f95b455427d4d7bb8f9b1 Mon Sep 17 00:00:00 2001 +From 2bf3e8934eec9d68a83a20bbbe4087c3e3b6f71d Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 29 Jul 2024 10:41:23 +0200 -Subject: [PATCH 32/46] mf/sar: Allow starting audio renderer again after +Subject: [PATCH 33/49] mf/sar: Allow starting audio renderer again after pausing it. --- diff --git a/patches/wine-gst/0033-winegstreamer-Also-flush-token-queue-on-seek.patch b/patches/wine-gst/0034-winegstreamer-Also-flush-token-queue-on-seek.patch similarity index 80% rename from patches/wine-gst/0033-winegstreamer-Also-flush-token-queue-on-seek.patch rename to patches/wine-gst/0034-winegstreamer-Also-flush-token-queue-on-seek.patch index 26ad87cb6..92c20704f 100644 --- a/patches/wine-gst/0033-winegstreamer-Also-flush-token-queue-on-seek.patch +++ b/patches/wine-gst/0034-winegstreamer-Also-flush-token-queue-on-seek.patch @@ -1,7 +1,7 @@ -From 65d5d5d7621ac9d0f2cd2d1d84ab4815dc9996cf Mon Sep 17 00:00:00 2001 +From 0047ead50debb434b20c06ffc56cbf592e9fe92c Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Tue, 6 Aug 2024 23:53:39 +0200 -Subject: [PATCH 33/46] winegstreamer: Also flush token queue on seek. +Subject: [PATCH 34/49] winegstreamer: Also flush token queue on seek. This is needed by video_frame_sink in mfmediaengine to properly restart playback after pausing if the unpausing operation is a seek. @@ -10,10 +10,10 @@ operation is a seek. 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dlls/winegstreamer/media_source.c b/dlls/winegstreamer/media_source.c -index 1d989b7f21a..ea4a417aecd 100644 +index 4dd6db8c9f5..ceaad05e2c0 100644 --- a/dlls/winegstreamer/media_source.c +++ b/dlls/winegstreamer/media_source.c -@@ -630,7 +630,7 @@ static HRESULT media_source_start(struct media_source *source, IMFPresentationDe +@@ -759,7 +759,7 @@ static HRESULT media_source_start(struct media_source *source, IMFPresentationDe AM_SEEKING_AbsolutePositioning, AM_SEEKING_NoPositioning); for (i = 0; i < source->stream_count; i++) diff --git a/patches/wine-gst/0034-mf-session-Fix-pausing-a-media-session-when-the-medi.patch b/patches/wine-gst/0035-mf-session-Fix-pausing-a-media-session-when-the-medi.patch similarity index 90% rename from patches/wine-gst/0034-mf-session-Fix-pausing-a-media-session-when-the-medi.patch rename to patches/wine-gst/0035-mf-session-Fix-pausing-a-media-session-when-the-medi.patch index 14a7fc952..1740c6446 100644 --- a/patches/wine-gst/0034-mf-session-Fix-pausing-a-media-session-when-the-medi.patch +++ b/patches/wine-gst/0035-mf-session-Fix-pausing-a-media-session-when-the-medi.patch @@ -1,7 +1,7 @@ -From 4f5346315b583d86ab895a77503f67b90a5debd7 Mon Sep 17 00:00:00 2001 +From 54c89667f04907474169d104949b508e95f484c8 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 7 Aug 2024 02:09:31 +0200 -Subject: [PATCH 34/46] mf/session: Fix pausing a media session when the media +Subject: [PATCH 35/49] mf/session: Fix pausing a media session when the media source sends buffering events. --- @@ -9,10 +9,10 @@ Subject: [PATCH 34/46] mf/session: Fix pausing a media session when the media 1 file changed, 79 insertions(+), 46 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c -index e119755f732..eab36a88234 100644 +index 170a31ef2ad..c341a59f925 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c -@@ -262,6 +262,7 @@ struct media_session +@@ -261,6 +261,7 @@ struct media_session struct list commands; enum session_state state; DWORD caps; @@ -20,7 +20,7 @@ index e119755f732..eab36a88234 100644 CRITICAL_SECTION cs; }; -@@ -1179,6 +1180,38 @@ static void session_set_closed(struct media_session *session, HRESULT status) +@@ -1097,6 +1098,38 @@ static void session_set_closed(struct media_session *session, HRESULT status) session_command_complete_with_event(session, MESessionClosed, status, NULL); } @@ -59,7 +59,7 @@ index e119755f732..eab36a88234 100644 static void session_pause(struct media_session *session) { unsigned int state = ~0u; -@@ -1189,7 +1222,12 @@ static void session_pause(struct media_session *session) +@@ -1107,7 +1140,12 @@ static void session_pause(struct media_session *session) case SESSION_STATE_STARTED: /* Transition in two steps - pause the clock, wait for sinks, then pause sources. */ @@ -73,7 +73,7 @@ index e119755f732..eab36a88234 100644 session_set_state(session, SESSION_STATE_PAUSING_SINKS); state = SESSION_STATE_PAUSED; -@@ -1241,6 +1279,28 @@ static void session_set_stopped(struct media_session *session, HRESULT status) +@@ -1159,6 +1197,28 @@ static void session_set_stopped(struct media_session *session, HRESULT status) session_command_complete(session); } @@ -102,7 +102,7 @@ index e119755f732..eab36a88234 100644 static void session_stop(struct media_session *session) { HRESULT hr = MF_E_INVALIDREQUEST; -@@ -1252,7 +1312,12 @@ static void session_stop(struct media_session *session) +@@ -1170,7 +1230,12 @@ static void session_stop(struct media_session *session) /* Transition in two steps - stop the clock, wait for sinks, then stop sources. */ IMFPresentationClock_GetTime(session->clock, &session->presentation.clock_stop_time); @@ -116,7 +116,7 @@ index e119755f732..eab36a88234 100644 session_set_state(session, SESSION_STATE_STOPPING_SINKS); else session_set_stopped(session, hr); -@@ -1310,7 +1375,12 @@ static void session_close(struct media_session *session) +@@ -1228,7 +1293,12 @@ static void session_close(struct media_session *session) case SESSION_STATE_STARTED: case SESSION_STATE_PAUSED: session->presentation.flags |= SESSION_FLAG_FINALIZE_SINKS; @@ -130,7 +130,7 @@ index e119755f732..eab36a88234 100644 session_set_state(session, SESSION_STATE_STOPPING_SINKS); break; default: -@@ -2963,19 +3033,6 @@ static BOOL session_is_source_nodes_state(struct media_session *session, enum ob +@@ -2866,19 +2936,6 @@ static BOOL session_is_source_nodes_state(struct media_session *session, enum ob return TRUE; } @@ -150,7 +150,7 @@ index e119755f732..eab36a88234 100644 static enum object_state session_get_object_state_for_event(MediaEventType event) { switch (event) -@@ -3020,6 +3077,8 @@ static HRESULT session_start_clock(struct media_session *session) +@@ -2923,6 +2980,8 @@ static HRESULT session_start_clock(struct media_session *session) if (FAILED(hr = IMFPresentationClock_Start(session->clock, start_offset))) WARN("Failed to start session clock, hr %#lx.\n", hr); @@ -159,7 +159,7 @@ index e119755f732..eab36a88234 100644 return hr; } -@@ -3187,7 +3246,6 @@ static void session_set_source_object_state(struct media_session *session, IUnkn +@@ -3090,7 +3149,6 @@ static void session_set_source_object_state(struct media_session *session, IUnkn static void session_set_sink_stream_state(struct media_session *session, IMFStreamSink *stream, MediaEventType event_type) { @@ -167,7 +167,7 @@ index e119755f732..eab36a88234 100644 enum object_state state; HRESULT hr = S_OK; BOOL changed; -@@ -3214,38 +3272,12 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre +@@ -3117,38 +3175,12 @@ static void session_set_sink_stream_state(struct media_session *session, IMFStre session_set_started(session); break; case SESSION_STATE_PAUSING_SINKS: @@ -208,7 +208,7 @@ index e119755f732..eab36a88234 100644 break; default: ; -@@ -4138,8 +4170,9 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM +@@ -3814,8 +3846,9 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM { if (event_type == MEBufferingStarted) IMFPresentationClock_Pause(session->clock); diff --git a/patches/wine-gst/0035-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch b/patches/wine-gst/0036-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch similarity index 52% rename from patches/wine-gst/0035-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch rename to patches/wine-gst/0036-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch index 606d786c7..9fc7ff454 100644 --- a/patches/wine-gst/0035-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch +++ b/patches/wine-gst/0036-winegstreamer-Do-not-force-uridecodebin-to-expose-un.patch @@ -1,26 +1,19 @@ -From 6e0ed8f046e848ebfef445fcb7feb9315f4eb519 Mon Sep 17 00:00:00 2001 +From bf894a4e8cc7076b9d62a217c4ad00529ab8626c Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 10 Jul 2024 22:50:17 +0200 -Subject: [PATCH 35/46] winegstreamer: Do not force uridecodebin to expose +Subject: [PATCH 36/49] winegstreamer: Do not force uridecodebin to expose uncompressed streams by failing autoplug-continue callbacks. Doing so makes uridecodebin expose pads that do not respond to CAPS queries correctly for HLS sources. --- - dlls/winegstreamer/wg_parser.c | 15 +++++++++++++-- - 1 file changed, 13 insertions(+), 2 deletions(-) + dlls/winegstreamer/wg_parser.c | 11 ++++++++++- + 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 280d1e52528..cde47f1c26f 100644 +index b5acba93fdd..7915084ed5d 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -1436,15 +1436,26 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user) - { - struct wg_parser_stream *stream; - struct wg_parser *parser = user; -+ GstCaps *caps; - - GST_LOG("parser %p, element %p, pad %p.", parser, element, pad); - +@@ -1366,10 +1366,19 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user) if (gst_pad_is_linked(pad)) return; @@ -36,20 +29,11 @@ index 280d1e52528..cde47f1c26f 100644 + if (!(stream = create_stream(parser, gst_pad_get_stream_id(pad)))) return; -- stream->codec_caps = gst_pad_query_caps(pad, NULL); -+ stream->codec_caps = caps; - - /* For compressed stream, create an extra decodebin to decode it. */ - if (!parser->output_compressed && caps_is_compressed(stream->codec_caps)) -@@ -2383,7 +2394,7 @@ static BOOL uridecodebin_parser_init_gst(struct wg_parser *parser) - if (!(element = create_element("uridecodebin", "base"))) - return FALSE; -- parser->output_compressed = true; -+ parser->output_compressed = false; +- caps = gst_pad_query_caps(pad, NULL); + wg_format_from_caps(&stream->codec_format, caps); + gst_caps_unref(caps); - gst_bin_add(GST_BIN(parser->container), element); - parser->decodebin = element; -- 2.46.0 diff --git a/patches/wine-gst/0036-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch b/patches/wine-gst/0037-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch similarity index 85% rename from patches/wine-gst/0036-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch rename to patches/wine-gst/0037-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch index 4a95591fb..58730c5b8 100644 --- a/patches/wine-gst/0036-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch +++ b/patches/wine-gst/0037-mfmediaengine-Unstub-IMFMediaEngine-SetAutoPlay.patch @@ -1,17 +1,17 @@ -From 9e693363fe2066b7d39040d29c88c783c43fb51e Mon Sep 17 00:00:00 2001 +From 2c05f8c49e928aa11d4b41e7b5de4862f1ebfcb0 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 16 Aug 2024 02:29:05 +0200 -Subject: [PATCH 36/46] mfmediaengine: Unstub IMFMediaEngine::SetAutoPlay. +Subject: [PATCH 37/49] mfmediaengine: Unstub IMFMediaEngine::SetAutoPlay. --- dlls/mfmediaengine/main.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c -index fba338a8438..7bf51afcf82 100644 +index a40f8d64f58..bd844bace6c 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c -@@ -1434,7 +1434,7 @@ static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface, +@@ -1436,7 +1436,7 @@ static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface, engine->network_state = MF_MEDIA_ENGINE_NETWORK_LOADING; IMFMediaEngineNotify_EventNotify(engine->callback, MF_MEDIA_ENGINE_EVENT_LOADSTART, 0, 0); @@ -20,7 +20,7 @@ index fba338a8438..7bf51afcf82 100644 media_engine_set_flag(engine, FLAGS_ENGINE_SOURCE_PENDING | FLAGS_ENGINE_PLAY_PENDING, FALSE); if (SUCCEEDED(IMFAsyncResult_GetState(result, &state))) -@@ -2050,14 +2050,19 @@ static BOOL WINAPI media_engine_GetAutoPlay(IMFMediaEngineEx *iface) +@@ -2052,14 +2052,19 @@ static BOOL WINAPI media_engine_GetAutoPlay(IMFMediaEngineEx *iface) static HRESULT WINAPI media_engine_SetAutoPlay(IMFMediaEngineEx *iface, BOOL autoplay) { struct media_engine *engine = impl_from_IMFMediaEngineEx(iface); diff --git a/patches/wine-gst/0037-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch b/patches/wine-gst/0038-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch similarity index 80% rename from patches/wine-gst/0037-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch rename to patches/wine-gst/0038-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch index 1554704d9..3adf9e065 100644 --- a/patches/wine-gst/0037-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch +++ b/patches/wine-gst/0038-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch @@ -1,7 +1,7 @@ -From 4d4ce8b73809fc67cea763a6525bd8d3b473902a Mon Sep 17 00:00:00 2001 +From 000f8b77e897bdacf3e4b89f84a33b242d422c80 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:54 +0100 -Subject: [PATCH 37/46] [HACK] winegstreamer: Add a resampler to wg_parser for +Subject: [PATCH 38/49] [HACK] winegstreamer: Add a resampler to wg_parser for raw audio. --- @@ -9,10 +9,10 @@ Subject: [PATCH 37/46] [HACK] winegstreamer: Add a resampler to wg_parser for 1 file changed, 4 insertions(+) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index cde47f1c26f..31cdbe8607c 100644 +index 7915084ed5d..9e281c330b8 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -1368,6 +1368,10 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser +@@ -1291,6 +1291,10 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser if (!(element = create_element("audioconvert", "base")) || !append_element(parser->container, element, &first, &last)) return false; diff --git a/patches/wine-gst/0038-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch b/patches/wine-gst/0039-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch similarity index 83% rename from patches/wine-gst/0038-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch rename to patches/wine-gst/0039-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch index 71108c3df..13f79d924 100644 --- a/patches/wine-gst/0038-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch +++ b/patches/wine-gst/0039-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch @@ -1,7 +1,7 @@ -From 114772429100b7664bdc3cc27dfe078375a28d76 Mon Sep 17 00:00:00 2001 +From 5c6edafba7ac309617a203ff3052929fa79bf2c2 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 31 Jan 2024 17:42:54 +0100 -Subject: [PATCH 38/46] [HACK] winegstreamer: Add a videoscale element to +Subject: [PATCH 39/49] [HACK] winegstreamer: Add a videoscale element to wg_parser for raw video. --- @@ -9,10 +9,10 @@ Subject: [PATCH 38/46] [HACK] winegstreamer: Add a videoscale element to 1 file changed, 9 insertions(+) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 31cdbe8607c..1b252f4dc60 100644 +index 9e281c330b8..8907159a6ac 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -1276,6 +1276,10 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser +@@ -1199,6 +1199,10 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser if (!(element = create_element("gldownload", "base")) || !append_element(parser->container, element, &first, &last)) return false; @@ -23,7 +23,7 @@ index 31cdbe8607c..1b252f4dc60 100644 if (!link_src_to_element(pad, first) || !link_element_to_sink(last, stream->my_sink)) return false; -@@ -1356,6 +1360,11 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser +@@ -1279,6 +1283,11 @@ static bool stream_create_post_processing_elements(GstPad *pad, struct wg_parser /* Let GStreamer choose a default number of threads. */ gst_util_set_object_arg(G_OBJECT(element), "n-threads", "0"); diff --git a/patches/wine-gst/0039-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch b/patches/wine-gst/0040-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch similarity index 89% rename from patches/wine-gst/0039-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch rename to patches/wine-gst/0040-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch index a23310a09..da9341426 100644 --- a/patches/wine-gst/0039-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch +++ b/patches/wine-gst/0040-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch @@ -1,7 +1,7 @@ -From 90db7696268497e51bcf961a1e5b77da65da946d Mon Sep 17 00:00:00 2001 +From 2e0f8ccdcf8de7e1706b9e8490588c46cfbee720 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Sat, 2 Mar 2024 21:19:25 +0100 -Subject: [PATCH 39/46] [HACK] mfmediaengine: Do not send +Subject: [PATCH 40/49] [HACK] mfmediaengine: Do not send MF_MEDIA_ENGINE_EVENT_ERROR for VRChat. Breaks AVPro Video (used by VRChat) when a IMFMediaEngine::GetError call inside the event handler doesn't return an @@ -15,10 +15,10 @@ properly. In the meantime, this hack works around the problem. 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/dlls/mfmediaengine/main.c b/dlls/mfmediaengine/main.c -index 7bf51afcf82..4c15e133053 100644 +index bd844bace6c..176ad38e1c1 100644 --- a/dlls/mfmediaengine/main.c +++ b/dlls/mfmediaengine/main.c -@@ -1466,11 +1466,21 @@ static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface, +@@ -1468,11 +1468,21 @@ static HRESULT WINAPI media_engine_load_handler_Invoke(IMFAsyncCallback *iface, } else { diff --git a/patches/wine-gst/0040-Marker-commit-do-not-put-into-MR.patch b/patches/wine-gst/0041-Marker-commit-do-not-put-into-MR.patch similarity index 55% rename from patches/wine-gst/0040-Marker-commit-do-not-put-into-MR.patch rename to patches/wine-gst/0041-Marker-commit-do-not-put-into-MR.patch index 71d7752a4..b6ef30ad4 100644 --- a/patches/wine-gst/0040-Marker-commit-do-not-put-into-MR.patch +++ b/patches/wine-gst/0041-Marker-commit-do-not-put-into-MR.patch @@ -1,17 +1,17 @@ -From 719a2b7f8081ef949322841eef60658a0320adf6 Mon Sep 17 00:00:00 2001 +From 96f912f95de023a6810fba798c3307ec8a20cf14 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Mon, 25 Mar 2024 09:58:04 +0100 -Subject: [PATCH 40/46] === Marker commit, do not put into MR === +Subject: [PATCH 41/49] === Marker commit, do not put into MR === --- MAINTAINERS | 1 + 1 file changed, 1 insertion(+) diff --git a/MAINTAINERS b/MAINTAINERS -index a414cc846c8..8fe2ee79f1d 100644 +index ab42dff2884..f8890de4743 100644 --- a/MAINTAINERS +++ b/MAINTAINERS -@@ -437,3 +437,4 @@ P: Erich E. Hoover +@@ -438,3 +438,4 @@ P: Erich E. Hoover W: https://wine-staging.com/ seek diff --git a/patches/wine-gst/0045-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch b/patches/wine-gst/0042-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch similarity index 96% rename from patches/wine-gst/0045-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch rename to patches/wine-gst/0042-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch index b27996216..13ab0b729 100644 --- a/patches/wine-gst/0045-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch +++ b/patches/wine-gst/0042-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch @@ -1,7 +1,7 @@ -From 5048fc33b556e29dbbb45d1bbb1685bb157110be Mon Sep 17 00:00:00 2001 +From 933c1b42e16baf390ec45e30f43b868e66add60e Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Wed, 24 Apr 2024 22:00:49 +0200 -Subject: [PATCH 45/46] ntdll: Use unixcall instead of syscall for +Subject: [PATCH 42/49] ntdll: Use unixcall instead of syscall for QueryPerformanceCounter. --- diff --git a/patches/wine-gst/0043-quartz-Fix-buffer-overflow-when-passing-url-as-filen.patch b/patches/wine-gst/0043-quartz-Fix-buffer-overflow-when-passing-url-as-filen.patch new file mode 100644 index 000000000..b39cfb3b5 --- /dev/null +++ b/patches/wine-gst/0043-quartz-Fix-buffer-overflow-when-passing-url-as-filen.patch @@ -0,0 +1,26 @@ +From 1c93f539054a0ad026f1cf0792e85886c3dcd573 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Mon, 26 Aug 2024 16:15:16 +0200 +Subject: [PATCH 43/49] quartz: Fix buffer overflow when passing url as + filename to FilterGraph2_AddSourceFilter. + +--- + dlls/quartz/filesource.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/quartz/filesource.c b/dlls/quartz/filesource.c +index 7d6292df579..9d823662427 100644 +--- a/dlls/quartz/filesource.c ++++ b/dlls/quartz/filesource.c +@@ -191,7 +191,7 @@ BOOL get_media_type(const WCHAR *filename, GUID *majortype, GUID *subtype, GUID + WCHAR guidstr[39]; + HKEY key; + +- wcscat(extensions_path, ext); ++ wcsncat(extensions_path, ext, ARRAY_SIZE(extensions_path)); + if (!RegOpenKeyExW(HKEY_CLASSES_ROOT, extensions_path, 0, KEY_READ, &key)) + { + size = sizeof(guidstr); +-- +2.46.0 + diff --git a/patches/wine-gst/0044-mfplat-Allocate-memory-buffers-using-calloc.patch b/patches/wine-gst/0044-mfplat-Allocate-memory-buffers-using-calloc.patch new file mode 100644 index 000000000..9306c5c0e --- /dev/null +++ b/patches/wine-gst/0044-mfplat-Allocate-memory-buffers-using-calloc.patch @@ -0,0 +1,76 @@ +From d19dc81ab7023ec68b0c1de410c14714da0caac3 Mon Sep 17 00:00:00 2001 +From: Torge Matthies +Date: Mon, 26 Aug 2024 19:12:39 +0200 +Subject: [PATCH 44/49] mfplat: Allocate memory buffers using calloc. + +Skips the need to memset the allocated memory. +--- + dlls/mfplat/buffer.c | 16 ++++++++++++---- + 1 file changed, 12 insertions(+), 4 deletions(-) + +diff --git a/dlls/mfplat/buffer.c b/dlls/mfplat/buffer.c +index b7f32f12cdc..44048c8f4af 100644 +--- a/dlls/mfplat/buffer.c ++++ b/dlls/mfplat/buffer.c +@@ -18,6 +18,7 @@ + + #define COBJMACROS + ++#include + #include + + #include "mfplat_private.h" +@@ -31,6 +32,7 @@ + WINE_DEFAULT_DEBUG_CHANNEL(mfplat); + + #define ALIGN_SIZE(size, alignment) (((size) + (alignment)) & ~((alignment))) ++#define ALIGN_PTR(ptr, alignment) ((void*)ALIGN_SIZE((DWORD_PTR)(ptr), (DWORD_PTR)(alignment))) + + typedef void (*p_copy_image_func)(BYTE *dest, LONG dest_stride, const BYTE *src, LONG src_stride, DWORD width, DWORD lines); + +@@ -42,7 +44,7 @@ struct buffer + IMFGetService IMFGetService_iface; + LONG refcount; + +- BYTE *data; ++ BYTE *unaligned_data, *data; + DWORD max_length; + DWORD current_length; + +@@ -173,7 +175,7 @@ static ULONG WINAPI memory_buffer_Release(IMFMediaBuffer *iface) + } + DeleteCriticalSection(&buffer->cs); + free(buffer->_2d.linear_buffer); +- _aligned_free(buffer->data); ++ free(buffer->unaligned_data); + free(buffer); + } + +@@ -1335,6 +1337,8 @@ static const IMFDXGIBufferVtbl dxgi_buffer_vtbl = + static HRESULT memory_buffer_init(struct buffer *buffer, DWORD max_length, DWORD alignment, + const IMFMediaBufferVtbl *vtbl) + { ++ DWORD total_length = max_length; ++ + if (alignment < MF_16_BYTE_ALIGNMENT) + alignment = MF_16_BYTE_ALIGNMENT; + alignment++; +@@ -1350,9 +1354,13 @@ static HRESULT memory_buffer_init(struct buffer *buffer, DWORD max_length, DWORD + alignment++; + } + +- if (!(buffer->data = _aligned_malloc(max_length, alignment))) ++ if (alignment > MEMORY_ALLOCATION_ALIGNMENT) ++ total_length += alignment - 1; ++ if (!(buffer->unaligned_data = calloc(1, total_length))) + return E_OUTOFMEMORY; +- memset(buffer->data, 0, max_length); ++ assert(alignment > MEMORY_ALLOCATION_ALIGNMENT || ++ ((DWORD_PTR)buffer->unaligned_data % MEMORY_ALLOCATION_ALIGNMENT) == 0); ++ buffer->data = ALIGN_PTR(buffer->unaligned_data, alignment - 1); + + buffer->IMFMediaBuffer_iface.lpVtbl = vtbl; + buffer->refcount = 1; +-- +2.46.0 + diff --git a/patches/wine-gst/0041-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch b/patches/wine-gst/0045-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch similarity index 80% rename from patches/wine-gst/0041-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch rename to patches/wine-gst/0045-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch index 1914edc8f..16819e1d0 100644 --- a/patches/wine-gst/0041-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch +++ b/patches/wine-gst/0045-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch @@ -1,17 +1,17 @@ -From 1912edea5c9e3542b495fcdee7ca8b7932bea483 Mon Sep 17 00:00:00 2001 +From 0a188f9b782a562129db01122aa1ac0282898c38 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Tue, 19 Mar 2024 10:20:49 +0100 -Subject: [PATCH 41/46] [DEBUG] winegstreamer: GST_LOG -> GST_DEBUG. +Subject: [PATCH 45/49] [DEBUG] winegstreamer: GST_LOG -> GST_DEBUG. --- dlls/winegstreamer/wg_parser.c | 34 +++++++++++++++++----------------- 1 file changed, 17 insertions(+), 17 deletions(-) diff --git a/dlls/winegstreamer/wg_parser.c b/dlls/winegstreamer/wg_parser.c -index 1b252f4dc60..2b641ba67c7 100644 +index 8907159a6ac..d80d6757774 100644 --- a/dlls/winegstreamer/wg_parser.c +++ b/dlls/winegstreamer/wg_parser.c -@@ -701,7 +701,7 @@ static NTSTATUS wg_parser_stream_notify_qos(void *args) +@@ -627,7 +627,7 @@ static NTSTATUS wg_parser_stream_notify_qos(void *args) /* This can happen legitimately if the sample falls outside of the * segment bounds. GStreamer elements shouldn't present the sample in * that case, but DirectShow doesn't care. */ @@ -20,7 +20,7 @@ index 1b252f4dc60..2b641ba67c7 100644 return S_OK; } if (!(event = gst_event_new_qos(params->underflow ? GST_QOS_TYPE_UNDERFLOW : GST_QOS_TYPE_OVERFLOW, -@@ -918,7 +918,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -807,7 +807,7 @@ static gboolean sink_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) struct wg_parser_stream *stream = gst_pad_get_element_private(pad); struct wg_parser *parser = stream->parser; @@ -29,7 +29,7 @@ index 1b252f4dc60..2b641ba67c7 100644 switch (event->type) { -@@ -1032,7 +1032,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu +@@ -923,7 +923,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu struct wg_parser_stream *stream = gst_pad_get_element_private(pad); struct wg_parser *parser = stream->parser; @@ -38,7 +38,7 @@ index 1b252f4dc60..2b641ba67c7 100644 pthread_mutex_lock(&parser->mutex); -@@ -1058,7 +1058,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu +@@ -949,7 +949,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu if (!stream->enabled) { @@ -47,7 +47,7 @@ index 1b252f4dc60..2b641ba67c7 100644 pthread_mutex_unlock(&parser->mutex); gst_buffer_unref(buffer); return GST_FLOW_OK; -@@ -1089,7 +1089,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu +@@ -980,7 +980,7 @@ static GstFlowReturn sink_chain_cb(GstPad *pad, GstObject *parent, GstBuffer *bu * reference to the stream object, which will release it in * wg_parser_stream_release_buffer(). */ @@ -56,7 +56,7 @@ index 1b252f4dc60..2b641ba67c7 100644 return GST_FLOW_OK; } -@@ -1098,7 +1098,7 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) +@@ -1026,7 +1026,7 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) struct wg_parser_stream *stream = gst_pad_get_element_private(pad); struct wg_parser *parser = stream->parser; @@ -65,7 +65,7 @@ index 1b252f4dc60..2b641ba67c7 100644 switch (query->type) { -@@ -1130,7 +1130,7 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) +@@ -1054,7 +1054,7 @@ static gboolean sink_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) gst_structure_remove_fields(gst_caps_get_structure(caps, i), "framerate", "pixel-aspect-ratio", NULL); @@ -74,7 +74,7 @@ index 1b252f4dc60..2b641ba67c7 100644 if (filter) { -@@ -1411,7 +1411,7 @@ static void stream_decodebin_pad_added_cb(GstElement *element, GstPad *pad, gpoi +@@ -1334,7 +1334,7 @@ static void stream_decodebin_pad_added_cb(GstElement *element, GstPad *pad, gpoi struct wg_parser_stream *stream = user; struct wg_parser *parser = stream->parser; @@ -83,7 +83,7 @@ index 1b252f4dc60..2b641ba67c7 100644 if (gst_pad_is_linked(pad)) return; -@@ -1425,7 +1425,7 @@ static bool stream_decodebin_create(struct wg_parser_stream *stream) +@@ -1348,7 +1348,7 @@ static bool stream_decodebin_create(struct wg_parser_stream *stream) { struct wg_parser *parser = stream->parser; @@ -92,7 +92,7 @@ index 1b252f4dc60..2b641ba67c7 100644 if (!(stream->decodebin = create_element("decodebin", "base"))) return false; -@@ -1440,7 +1440,7 @@ static bool stream_decodebin_create(struct wg_parser_stream *stream) +@@ -1363,7 +1363,7 @@ static bool stream_decodebin_create(struct wg_parser_stream *stream) pthread_mutex_unlock(&parser->mutex); gst_element_sync_state_with_parent(stream->decodebin); @@ -101,7 +101,7 @@ index 1b252f4dc60..2b641ba67c7 100644 return true; } -@@ -1451,7 +1451,7 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user) +@@ -1374,7 +1374,7 @@ static void pad_added_cb(GstElement *element, GstPad *pad, gpointer user) struct wg_parser *parser = user; GstCaps *caps; @@ -110,7 +110,7 @@ index 1b252f4dc60..2b641ba67c7 100644 if (gst_pad_is_linked(pad)) return; -@@ -1498,7 +1498,7 @@ static void pad_removed_cb(GstElement *element, GstPad *pad, gpointer user) +@@ -1423,7 +1423,7 @@ static void pad_removed_cb(GstElement *element, GstPad *pad, gpointer user) unsigned int i; char *name; @@ -119,7 +119,7 @@ index 1b252f4dc60..2b641ba67c7 100644 for (i = 0; i < parser->stream_count; ++i) { -@@ -1557,7 +1557,7 @@ static GstFlowReturn issue_read_request(struct wg_parser *parser, guint64 offset +@@ -1482,7 +1482,7 @@ static GstFlowReturn issue_read_request(struct wg_parser *parser, guint64 offset pthread_mutex_unlock(&parser->mutex); @@ -128,7 +128,7 @@ index 1b252f4dc60..2b641ba67c7 100644 return ret; } -@@ -1666,7 +1666,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, +@@ -1591,7 +1591,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, { struct wg_parser *parser = gst_pad_get_element_private(pad); @@ -137,7 +137,7 @@ index 1b252f4dc60..2b641ba67c7 100644 if (offset == GST_BUFFER_OFFSET_NONE) offset = parser->next_pull_offset; -@@ -1680,7 +1680,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, +@@ -1605,7 +1605,7 @@ static GstFlowReturn src_getrange_cb(GstPad *pad, GstObject *parent, if (!*buffer) *buffer = gst_buffer_new_and_alloc(0); gst_buffer_set_size(*buffer, 0); @@ -146,7 +146,7 @@ index 1b252f4dc60..2b641ba67c7 100644 return GST_FLOW_OK; } -@@ -1701,7 +1701,7 @@ static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) +@@ -1626,7 +1626,7 @@ static gboolean src_query_cb(GstPad *pad, GstObject *parent, GstQuery *query) struct wg_parser *parser = gst_pad_get_element_private(pad); GstFormat format; @@ -155,7 +155,7 @@ index 1b252f4dc60..2b641ba67c7 100644 switch (GST_QUERY_TYPE(query)) { -@@ -2005,7 +2005,7 @@ static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) +@@ -1930,7 +1930,7 @@ static gboolean src_event_cb(GstPad *pad, GstObject *parent, GstEvent *event) struct wg_parser *parser = gst_pad_get_element_private(pad); gboolean ret = TRUE; diff --git a/patches/wine-gst/0042-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch b/patches/wine-gst/0046-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch similarity index 92% rename from patches/wine-gst/0042-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch rename to patches/wine-gst/0046-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch index 0468115c5..45c37f2ce 100644 --- a/patches/wine-gst/0042-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch +++ b/patches/wine-gst/0046-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch @@ -1,7 +1,7 @@ -From 152841cbdd14102620529a7accbc02bfec9731b5 Mon Sep 17 00:00:00 2001 +From d9c2cacdaa98534ec969baf4e361d5ba7004d308 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Thu, 28 Mar 2024 16:43:07 +0100 -Subject: [PATCH 42/46] [HACK] kernelbase: yt-dlp.exe redirection and cmdline +Subject: [PATCH 46/49] [HACK] kernelbase: yt-dlp.exe redirection and cmdline modification to read cookies from browser. --- @@ -9,7 +9,7 @@ Subject: [PATCH 42/46] [HACK] kernelbase: yt-dlp.exe redirection and cmdline 1 file changed, 51 insertions(+) diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c -index 387ae09bc11..f716d0bf35f 100644 +index abf789d6033..163e15d920a 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -584,6 +584,54 @@ static int battleye_launcher_redirect_hack( const WCHAR *app_name, WCHAR *new_na @@ -67,7 +67,7 @@ index 387ae09bc11..f716d0bf35f 100644 static const WCHAR *hack_append_command_line( const WCHAR *cmd ) { static const struct -@@ -713,6 +761,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR +@@ -714,6 +762,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR if (battleye_launcher_redirect_hack( app_name, name, ARRAY_SIZE(name), &orig_app_name )) app_name = name; diff --git a/patches/wine-gst/0043-mf-Schedule-stored-timers-for-the-original-time-inst.patch b/patches/wine-gst/0047-mf-Schedule-stored-timers-for-the-original-time-inst.patch similarity index 95% rename from patches/wine-gst/0043-mf-Schedule-stored-timers-for-the-original-time-inst.patch rename to patches/wine-gst/0047-mf-Schedule-stored-timers-for-the-original-time-inst.patch index d0a9e249e..c07f37305 100644 --- a/patches/wine-gst/0043-mf-Schedule-stored-timers-for-the-original-time-inst.patch +++ b/patches/wine-gst/0047-mf-Schedule-stored-timers-for-the-original-time-inst.patch @@ -1,7 +1,7 @@ -From 1fe3dd8e9558fee3bb18e94c320886475c9cf388 Mon Sep 17 00:00:00 2001 +From 85969d22ab64e0dcdeb33e0354ad7a1617c765c1 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 23 Feb 2024 21:45:44 +0100 -Subject: [PATCH 43/46] mf: Schedule stored timers for the original time +Subject: [PATCH 47/49] mf: Schedule stored timers for the original time instead of calling callbacks immediately when changing presentation clock state. diff --git a/patches/wine-gst/0044-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch b/patches/wine-gst/0048-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch similarity index 79% rename from patches/wine-gst/0044-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch rename to patches/wine-gst/0048-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch index b33f85c0e..a9de91586 100644 --- a/patches/wine-gst/0044-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch +++ b/patches/wine-gst/0048-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch @@ -1,33 +1,27 @@ -From 2e09637d4741e98f8243886fe106ffcbcae7ffdf Mon Sep 17 00:00:00 2001 +From d29981a70cf0633884153b3d454463844131d0ed Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Fri, 23 Feb 2024 21:50:22 +0100 -Subject: [PATCH 44/46] mf: Start forwarding samples only at the PTS of the +Subject: [PATCH 48/49] mf: Start forwarding samples only at the PTS of the first sample. Hides desynchronization in applications that ignore the PTS, e.g. VRChat. --- - dlls/mf/session.c | 182 ++++++++++++++++++++++++++++++++++++++++++++-- - 1 file changed, 177 insertions(+), 5 deletions(-) + dlls/mf/session.c | 179 ++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 172 insertions(+), 7 deletions(-) diff --git a/dlls/mf/session.c b/dlls/mf/session.c -index eab36a88234..250dd461512 100644 +index c341a59f925..4da68960e7e 100644 --- a/dlls/mf/session.c +++ b/dlls/mf/session.c -@@ -164,6 +164,13 @@ enum topo_node_flags +@@ -163,6 +163,7 @@ enum topo_node_flags { TOPO_NODE_END_OF_STREAM = 0x1, TOPO_NODE_SCRUB_SAMPLE_COMPLETE = 0x2, + TOPO_NODE_HAS_WAITED_FOR_PTS = 0x4, -+}; -+ -+struct sample -+{ -+ struct list entry; -+ IMFSample *sample; }; struct topo_node -@@ -189,6 +196,9 @@ struct topo_node +@@ -188,6 +189,9 @@ struct topo_node { IMFMediaSource *source; DWORD stream_id; @@ -37,7 +31,7 @@ index eab36a88234..250dd461512 100644 } source; struct { -@@ -239,6 +249,7 @@ struct media_session +@@ -238,6 +242,7 @@ struct media_session IMFPresentationClock *clock; IMFPresentationTimeSource *system_time_source; IMFRateControl *clock_rate_control; @@ -45,7 +39,7 @@ index eab36a88234..250dd461512 100644 IMFTopoLoader *topo_loader; IMFQualityManager *quality_manager; struct -@@ -316,6 +327,11 @@ static struct session_op *impl_op_from_IUnknown(IUnknown *iface) +@@ -315,6 +320,11 @@ static struct session_op *impl_op_from_IUnknown(IUnknown *iface) return CONTAINING_RECORD(iface, struct session_op, IUnknown_iface); } @@ -57,8 +51,8 @@ index eab36a88234..250dd461512 100644 static struct topo_node *impl_node_from_IMFVideoSampleAllocatorNotify(IMFVideoSampleAllocatorNotify *iface) { return CONTAINING_RECORD(iface, struct topo_node, u.sink.notify_cb); -@@ -788,6 +804,29 @@ static void transform_stream_drop_events(struct transform_stream *stream) - IMFMediaEvent_Release(event); +@@ -740,6 +750,29 @@ static void transform_stream_drop_samples(struct transform_stream *stream) + IMFSample_Release(sample); } +static HRESULT topo_node_sourcestream_pop_sample(struct topo_node *source_node, IMFSample **sample) @@ -87,7 +81,7 @@ index eab36a88234..250dd461512 100644 static void release_topo_node(struct topo_node *node) { unsigned int i; -@@ -797,6 +836,12 @@ static void release_topo_node(struct topo_node *node) +@@ -749,6 +782,12 @@ static void release_topo_node(struct topo_node *node) case MF_TOPOLOGY_SOURCESTREAM_NODE: if (node->u.source.source) IMFMediaSource_Release(node->u.source.source); @@ -100,7 +94,7 @@ index eab36a88234..250dd461512 100644 break; case MF_TOPOLOGY_TRANSFORM_NODE: for (i = 0; i < node->u.transform.input_count; ++i) -@@ -1815,6 +1860,68 @@ static HRESULT session_get_stream_sink_type(IMFStreamSink *sink, IMFMediaType ** +@@ -1733,6 +1772,68 @@ static HRESULT session_get_stream_sink_type(IMFStreamSink *sink, IMFMediaType ** return hr; } @@ -169,7 +163,7 @@ index eab36a88234..250dd461512 100644 static HRESULT WINAPI node_sample_allocator_cb_QueryInterface(IMFVideoSampleAllocatorNotify *iface, REFIID riid, void **obj) { -@@ -1929,6 +2036,9 @@ static HRESULT session_append_node(struct media_session *session, IMFTopologyNod +@@ -1830,6 +1931,9 @@ static HRESULT session_append_node(struct media_session *session, IMFTopologyNod break; case MF_TOPOLOGY_SOURCESTREAM_NODE: @@ -179,7 +173,7 @@ index eab36a88234..250dd461512 100644 if (FAILED(IMFTopologyNode_GetUnknown(node, &MF_TOPONODE_SOURCE, &IID_IMFMediaSource, (void **)&topo_node->u.source.source))) { -@@ -2231,6 +2341,8 @@ static ULONG WINAPI mfsession_Release(IMFMediaSession *iface) +@@ -2132,6 +2236,8 @@ static ULONG WINAPI mfsession_Release(IMFMediaSession *iface) IMFPresentationTimeSource_Release(session->system_time_source); if (session->clock_rate_control) IMFRateControl_Release(session->clock_rate_control); @@ -188,8 +182,8 @@ index eab36a88234..250dd461512 100644 if (session->topo_loader) IMFTopoLoader_Release(session->topo_loader); if (session->quality_manager) -@@ -3893,10 +4005,40 @@ static void session_request_sample(struct media_session *session, IMFStreamSink - sink_node->u.sink.requests--; +@@ -3566,11 +3672,41 @@ static void session_request_sample(struct media_session *session, IMFStreamSink + IMFTopologyNode_Release(upstream_node); } +static HRESULT topo_node_sourcestream_push_sample(struct topo_node *source_node, IMFSample *sample) @@ -209,28 +203,30 @@ index eab36a88234..250dd461512 100644 +static void session_deliver_sample_from_source(struct media_session *session, struct topo_node *source_node, + IMFSample *sample) +{ -+ struct topo_node *node; -+ DWORD input; ++ IMFTopologyNode *downstream_node; ++ DWORD downstream_input; ++ HRESULT hr; + -+ if (!(node = session_get_topo_node_output(session, source_node, 0, &input))) ++ if (FAILED(hr = IMFTopologyNode_GetOutput(source_node->node, 0, &downstream_node, &downstream_input))) + { -+ WARN("Failed to node %p/%u output.\n", source_node, 0); ++ WARN("Failed to get downstream node connection, hr %#lx.\n", hr); + return; + } + -+ session_deliver_sample_to_node(session, node, input, sample); ++ session_deliver_sample_to_node(session, downstream_node, downstream_input, sample); ++ IMFTopologyNode_Release(downstream_node); +} + static void session_deliver_sample(struct media_session *session, IMFMediaStream *stream, const PROPVARIANT *value) { struct topo_node *source_node = NULL, *node; -- DWORD input; +- IMFTopologyNode *downstream_node; +- DWORD downstream_input; + IMFSample *sample; -+ HRESULT hr; + HRESULT hr; if (value && (value->vt != VT_UNKNOWN || !value->punkVal)) - { -@@ -3916,16 +4058,42 @@ static void session_deliver_sample(struct media_session *session, IMFMediaStream +@@ -3591,17 +3727,42 @@ static void session_deliver_sample(struct media_session *session, IMFMediaStream if (!source_node) return; @@ -239,10 +235,10 @@ index eab36a88234..250dd461512 100644 if (!value) source_node->flags |= TOPO_NODE_END_OF_STREAM; - -- if (!(node = session_get_topo_node_output(session, source_node, 0, &input))) +- if (FAILED(hr = IMFTopologyNode_GetOutput(source_node->node, 0, &downstream_node, &downstream_input))) + else if (!(source_node->flags & TOPO_NODE_HAS_WAITED_FOR_PTS)) { -- WARN("Failed to node %p/%u output.\n", source_node, 0); +- WARN("Failed to get downstream node connection, hr %#lx.\n", hr); + LONGLONG sampletime; + + source_node->flags |= TOPO_NODE_HAS_WAITED_FOR_PTS; @@ -272,12 +268,13 @@ index eab36a88234..250dd461512 100644 return; } -- session_deliver_sample_to_node(session, node, input, value ? (IMFSample *)value->punkVal : NULL); -+ session_deliver_sample_from_source(session, node, sample); +- session_deliver_sample_to_node(session, downstream_node, downstream_input, value ? (IMFSample *)value->punkVal : NULL); +- IMFTopologyNode_Release(downstream_node); ++ session_deliver_sample_from_source(session, source_node, sample); } static void session_sink_invalidated(struct media_session *session, IMFMediaEvent *event, IMFStreamSink *sink) -@@ -4720,6 +4888,10 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses +@@ -4396,6 +4557,10 @@ HRESULT WINAPI MFCreateMediaSession(IMFAttributes *config, IMFMediaSession **ses goto failed; } diff --git a/patches/wine-gst/0046-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch b/patches/wine-gst/0049-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch similarity index 86% rename from patches/wine-gst/0046-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch rename to patches/wine-gst/0049-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch index bf6b3900a..ad9b123bd 100644 --- a/patches/wine-gst/0046-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch +++ b/patches/wine-gst/0049-HACK-kernelbase-Replace-stderr-of-yt-dlp-process.patch @@ -1,14 +1,14 @@ -From 204b913a2943c173139028d2a81b3504f323df02 Mon Sep 17 00:00:00 2001 +From 80c2e192ecb2c3aeccb387f7d2f7a92d46fe5451 Mon Sep 17 00:00:00 2001 From: Torge Matthies Date: Thu, 25 Jul 2024 00:17:20 +0200 -Subject: [PATCH 46/46] [HACK] kernelbase: Replace stderr of yt-dlp process. +Subject: [PATCH 49/49] [HACK] kernelbase: Replace stderr of yt-dlp process. --- dlls/kernelbase/process.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/dlls/kernelbase/process.c b/dlls/kernelbase/process.c -index f716d0bf35f..e96867451fb 100644 +index 163e15d920a..dc03d6d121c 100644 --- a/dlls/kernelbase/process.c +++ b/dlls/kernelbase/process.c @@ -584,6 +584,25 @@ static int battleye_launcher_redirect_hack( const WCHAR *app_name, WCHAR *new_na @@ -37,7 +37,7 @@ index f716d0bf35f..e96867451fb 100644 static int ytdlp_hack( const WCHAR *app_name, WCHAR *new_name, DWORD new_name_len, WCHAR **cmdline ) { static const WCHAR ytdlp_exeW[] = L"yt-dlp.exe"; -@@ -761,6 +780,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR +@@ -762,6 +781,9 @@ BOOL WINAPI DECLSPEC_HOTPATCH CreateProcessInternalW( HANDLE token, const WCHAR if (battleye_launcher_redirect_hack( app_name, name, ARRAY_SIZE(name), &orig_app_name )) app_name = name;