Skip to content

Commit

Permalink
rtsp patchset 9
Browse files Browse the repository at this point in the history
  • Loading branch information
SpookySkeletons committed Jun 4, 2024
1 parent 3ec7374 commit 5ead147
Show file tree
Hide file tree
Showing 42 changed files with 1,824 additions and 164 deletions.
72 changes: 40 additions & 32 deletions patches/protonprep-valve-staging.sh
Original file line number Diff line number Diff line change
Expand Up @@ -299,38 +299,46 @@
patch -Np1 < ../patches/wine-hotfixes/pending/add-envvar-to-gate-media-converter.patch

echo "WINE: RTSP patch"
patch -Np1 < ../patches/wine-gst/0001-mf-session-Avoid-leaking-samples-in-transform_node_d.patch
patch -Np1 < ../patches/wine-gst/0002-Memory-leak-fixes.patch
patch -Np1 < ../patches/wine-gst/0003-winegstreamer-Connect-autoplug-continue-and-deep-ele.patch
patch -Np1 < ../patches/wine-gst/0004-winegstreamer-Do-not-create-a-read-thread-for-uridec.patch
patch -Np1 < ../patches/wine-gst/0005-winegstreamer-Ignore-an-assert-in-wg_parser.patch
patch -Np1 < ../patches/wine-gst/0006-winegstreamer-Fixate-caps-in-autoplug_continue_cb.patch
patch -Np1 < ../patches/wine-gst/0007-winegstreamer-Make-wg_parser-report-the-exact-suppor.patch
patch -Np1 < ../patches/wine-gst/0008-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch
patch -Np1 < ../patches/wine-gst/0009-winegstreamer-Fixate-caps-in-the-pad-added-callback.patch
patch -Np1 < ../patches/wine-gst/0010-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch
patch -Np1 < ../patches/wine-gst/0011-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch
patch -Np1 < ../patches/wine-gst/0012-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch
patch -Np1 < ../patches/wine-gst/0013-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch
patch -Np1 < ../patches/wine-gst/0014-winegstreamer-Don-t-only-accept-segment-events-when-.patch
patch -Np1 < ../patches/wine-gst/0015-winegstreamer-Convert-buffer-presentation-timestamps.patch
patch -Np1 < ../patches/wine-gst/0016-winegstreamer-Adjust-buffer-timestamps-after-seek.patch
patch -Np1 < ../patches/wine-gst/0017-winegstreamer-Reorder-parser-initialization-code-a-b.patch
patch -Np1 < ../patches/wine-gst/0018-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch
patch -Np1 < ../patches/wine-gst/0019-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch
patch -Np1 < ../patches/wine-gst/0020-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch
patch -Np1 < ../patches/wine-gst/0021-winegstreamer-Do-not-seek-live-sources.patch
patch -Np1 < ../patches/wine-gst/0022-winegstreamer-Implement-buffering-events.patch
patch -Np1 < ../patches/wine-gst/0023-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch
patch -Np1 < ../patches/wine-gst/0024-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch
patch -Np1 < ../patches/wine-gst/0025-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch
patch -Np1 < ../patches/wine-gst/0026-Marker-commit-do-not-put-into-MR.patch
patch -Np1 < ../patches/wine-gst/0027-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch
patch -Np1 < ../patches/wine-gst/0028-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch
patch -Np1 < ../patches/wine-gst/0029-mf-Schedule-stored-timers-for-the-original-time-inst.patch
patch -Np1 < ../patches/wine-gst/0030-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch
patch -Np1 < ../patches/wine-gst/0031-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch
patch -Np1 < ../patches/wine-gst/0032-mf-Send-sample-requests-for-unused-space-of-sample-q.patch
patch -Np1 < ../patches/wine-gst/0001-mf-Add-seeking-support-for-IMFMediaSession-Start.patch
patch -Np1 < ../patches/wine-gst/0002-mf-tests-Add-a-create_media_session_with_source_sink.patch
patch -Np1 < ../patches/wine-gst/0003-mf-tests-Test-IMFMediaSession-Start.patch
patch -Np1 < ../patches/wine-gst/0004-mfmediaengine-Implement-IMFMediaEngineEx-SetCurrentT.patch
patch -Np1 < ../patches/wine-gst/0005-mfmediaengine-tests-Test-IMFMediaEngineEx-SetCurrent.patch
patch -Np1 < ../patches/wine-gst/0006-AVPro-Video-seeking-support.patch
patch -Np1 < ../patches/wine-gst/0007-mf-session-Avoid-leaking-samples-in-transform_node_d.patch
patch -Np1 < ../patches/wine-gst/0008-Memory-leak-fixes.patch
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-Fixate-caps-in-autoplug_continue_cb.patch
patch -Np1 < ../patches/wine-gst/0013-winegstreamer-Make-wg_parser-report-the-exact-suppor.patch
patch -Np1 < ../patches/wine-gst/0014-winegstreamer-Add-more-RTSP-based-URI-schemes-to-GSt.patch
patch -Np1 < ../patches/wine-gst/0015-winegstreamer-Fixate-caps-in-the-pad-added-callback.patch
patch -Np1 < ../patches/wine-gst/0016-winegstreamer-Mark-wg_parser-container-bin-as-stream.patch
patch -Np1 < ../patches/wine-gst/0017-winegstreamer-Set-a-clock-for-the-wg_parser-pipeline.patch
patch -Np1 < ../patches/wine-gst/0018-winegstreamer-Set-base-time-on-wg_parser-bin-while-c.patch
patch -Np1 < ../patches/wine-gst/0019-winegstreamer-Put-pipeline-into-PLAYING-state-before.patch
patch -Np1 < ../patches/wine-gst/0020-winegstreamer-Don-t-only-accept-segment-events-when-.patch
patch -Np1 < ../patches/wine-gst/0021-winegstreamer-Convert-buffer-presentation-timestamps.patch
patch -Np1 < ../patches/wine-gst/0022-winegstreamer-Adjust-buffer-timestamps-after-seek.patch
patch -Np1 < ../patches/wine-gst/0023-winegstreamer-Reorder-parser-initialization-code-a-b.patch
patch -Np1 < ../patches/wine-gst/0024-winegstreamer-Do-away-with-the-per-stream-condvars-a.patch
patch -Np1 < ../patches/wine-gst/0025-winegstreamer-Use-pthread_cond_broadcast-instead-of-.patch
patch -Np1 < ../patches/wine-gst/0026-winegstreamer-Do-not-fail-caps-negotiation-when-ther.patch
patch -Np1 < ../patches/wine-gst/0027-winegstreamer-Do-not-seek-live-sources.patch
patch -Np1 < ../patches/wine-gst/0028-winegstreamer-Implement-buffering-events.patch
patch -Np1 < ../patches/wine-gst/0029-mf-Send-sample-requests-for-unused-space-of-sample-q.patch
patch -Np1 < ../patches/wine-gst/0030-winegstreamer-Add-a-queue-of-buffers-to-wg_parser-to.patch
patch -Np1 < ../patches/wine-gst/0031-winegstreamer-Fix-race-between-wg_parser_stream_disa.patch
patch -Np1 < ../patches/wine-gst/0032-HACK-winegstreamer-Add-a-resampler-to-wg_parser-for-.patch
patch -Np1 < ../patches/wine-gst/0033-HACK-winegstreamer-Add-a-videoscale-element-to-wg_pa.patch
patch -Np1 < ../patches/wine-gst/0034-HACK-mfmediaengine-Do-not-send-MF_MEDIA_ENGINE_EVENT.patch
patch -Np1 < ../patches/wine-gst/0035-Marker-commit-do-not-put-into-MR.patch
patch -Np1 < ../patches/wine-gst/0036-DEBUG-winegstreamer-GST_LOG-GST_DEBUG.patch
patch -Np1 < ../patches/wine-gst/0037-HACK-kernelbase-yt-dlp.exe-redirection-and-cmdline-m.patch
patch -Np1 < ../patches/wine-gst/0038-mf-Schedule-stored-timers-for-the-original-time-inst.patch
patch -Np1 < ../patches/wine-gst/0039-mf-Start-forwarding-samples-only-at-the-PTS-of-the-f.patch
patch -Np1 < ../patches/wine-gst/0040-ntdll-Use-unixcall-instead-of-syscall-for-QueryPerfo.patch

#echo "WINE: -Nvidia Reflex- Support VK_NV_low_latency2"
#patch -Np1 < ../patches/proton/83-nv_low_latency_wine.patch
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
From f09b36196097597be64e9c0be6e4cb8d5a394028 Mon Sep 17 00:00:00 2001
From: Zhiyi Zhang <[email protected]>
Date: Tue, 1 Aug 2023 10:52:21 +0800
Subject: [PATCH 01/41] 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 ef707dea4de..3f3be2b84b0 100644
--- a/dlls/mf/session.c
+++ b/dlls/mf/session.c
@@ -110,6 +110,7 @@ enum object_state
OBJ_STATE_STARTED,
OBJ_STATE_PAUSED,
OBJ_STATE_PREROLLED,
+ OBJ_STATE_SEEKING,
OBJ_STATE_INVALID,
};

@@ -912,10 +913,28 @@ static HRESULT session_subscribe_sources(struct media_session *session)
return hr;
}

+static void session_set_source_output_nodes_seeking(struct media_session *session)
+{
+ struct media_source *source;
+ struct topo_node *node;
+
+ LIST_FOR_EACH_ENTRY(source, &session->presentation.sources, struct media_source, entry)
+ {
+ source->state = OBJ_STATE_SEEKING;
+ }
+
+ LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry)
+ {
+ if (node->type == MF_TOPOLOGY_SOURCESTREAM_NODE || node->type == MF_TOPOLOGY_OUTPUT_NODE)
+ node->state = OBJ_STATE_SEEKING;
+ }
+}
+
static void session_start(struct media_session *session, const GUID *time_format, const PROPVARIANT *start_position)
{
struct media_source *source;
struct topo_node *topo_node;
+ MFTIME duration;
HRESULT hr;
UINT i;

@@ -932,6 +951,13 @@ static void session_start(struct media_session *session, const GUID *time_format

/* fallthrough */
case SESSION_STATE_PAUSED:
+ case SESSION_STATE_STARTED:
+ if (session->state == SESSION_STATE_STARTED && !(session->caps & MFSESSIONCAP_SEEK))
+ {
+ WARN("Seeking is not supported for this session.\n");
+ session_command_complete(session);
+ return;
+ }

session->presentation.time_format = *time_format;
session->presentation.start_position.vt = VT_EMPTY;
@@ -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)
{
+ hr = IMFPresentationDescriptor_GetUINT64(source->pd, &MF_PD_DURATION, (UINT64 *)&duration);
+ if (SUCCEEDED(hr) && start_position->vt == VT_I8&& start_position->hVal.QuadPart > duration)
+ {
+ WARN("Start position %s out of range, hr %#lx.\n", wine_dbgstr_longlong(start_position->hVal.QuadPart), hr);
+ session_command_complete_with_event(session, MESessionStarted, MF_E_INVALID_POSITION, NULL);
+ return;
+ }
+
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);
@@ -965,12 +999,22 @@ static void session_start(struct media_session *session, const GUID *time_format
}
}

+ if (session->state == SESSION_STATE_STARTED)
+ {
+ struct topo_node *node;
+
+ LIST_FOR_EACH_ENTRY(node, &session->presentation.nodes, struct topo_node, entry)
+ {
+ if (node->type == MF_TOPOLOGY_OUTPUT_NODE)
+ IMFStreamSink_Flush(node->object.sink_stream);
+ else if (node->type == MF_TOPOLOGY_TRANSFORM_NODE)
+ IMFTransform_ProcessMessage(node->object.transform, MFT_MESSAGE_COMMAND_FLUSH, 0);
+ }
+
+ session_set_source_output_nodes_seeking(session);
+ }
session->state = SESSION_STATE_STARTING_SOURCES;
break;
- case SESSION_STATE_STARTED:
- FIXME("Seeking is not implemented.\n");
- session_command_complete(session);
- break;
default:
session_command_complete_with_event(session, MESessionStarted, MF_E_INVALIDREQUEST, NULL);
break;
@@ -2206,6 +2250,9 @@ static HRESULT WINAPI mfsession_Start(IMFMediaSession *iface, const GUID *format
if (!start_position)
return E_POINTER;

+ if (FAILED(hr = session_is_shut_down(session)))
+ return hr;
+
if (FAILED(hr = create_session_op(SESSION_CMD_START, &op)))
return hr;

@@ -3714,8 +3761,6 @@ static HRESULT WINAPI session_events_callback_Invoke(IMFAsyncCallback *iface, IM
{
case MESourceSeeked:
case MEStreamSeeked:
- FIXME("Source/stream seeking, semi-stub!\n");
- /* fallthrough */
case MESourceStarted:
case MESourcePaused:
case MESourceStopped:
--
2.45.1

Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
From 13e5f023ec606fccf3d24e532e9bf4f11871107a Mon Sep 17 00:00:00 2001
From: Zhiyi Zhang <[email protected]>
Date: Tue, 8 Aug 2023 15:24:34 +0800
Subject: [PATCH 02/41] mf/tests: Add a create_media_session_with_source_sink()
helper.

---
dlls/mf/tests/mf.c | 92 ++++++++++++++++++++++++----------------------
1 file changed, 48 insertions(+), 44 deletions(-)

diff --git a/dlls/mf/tests/mf.c b/dlls/mf/tests/mf.c
index 0a34329bd75..e0bcedac20f 100644
--- a/dlls/mf/tests/mf.c
+++ b/dlls/mf/tests/mf.c
@@ -4995,6 +4995,53 @@ static void test_sample_grabber_is_mediatype_supported(void)
IMFSampleGrabberSinkCallback_Release(grabber_callback);
}

+/* create a media session with the specified source and sink */
+static void create_media_session_with_source_sink(IMFMediaSource *source, IMFActivate *sink_activate,
+ IMFMediaSession **session)
+{
+ IMFTopologyNode *src_node, *sink_node;
+ IMFPresentationDescriptor *pd;
+ IMFStreamDescriptor *sd;
+ IMFTopology *topology;
+ BOOL selected;
+ HRESULT hr;
+
+ hr = MFCreateMediaSession(NULL, session);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = MFCreateTopology(&topology);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = IMFTopology_AddNode(topology, sink_node);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = IMFTopology_AddNode(topology, src_node);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ ok(selected, "got selected %u.\n", !!selected);
+ 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);
+ hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_ALLOW_DECODER);
+ ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr);
+ hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, TRUE);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+ hr = IMFMediaSession_SetTopology(*session, 0, topology);
+ ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
+
+ IMFStreamDescriptor_Release(sd);
+ IMFPresentationDescriptor_Release(pd);
+ IMFTopologyNode_Release(src_node);
+ IMFTopologyNode_Release(sink_node);
+ IMFTopology_Release(topology);
+}
+
static void test_sample_grabber_orientation(GUID subtype)
{
media_type_desc video_rgb32_desc =
@@ -5004,17 +5051,12 @@ static void test_sample_grabber_orientation(GUID subtype)
};

struct test_grabber_callback *grabber_callback;
- IMFTopologyNode *src_node, *sink_node;
- IMFPresentationDescriptor *pd;
IMFAsyncCallback *callback;
IMFActivate *sink_activate;
IMFMediaType *output_type;
IMFMediaSession *session;
- IMFStreamDescriptor *sd;
IMFMediaSource *source;
- IMFTopology *topology;
PROPVARIANT propvar;
- BOOL selected;
HRESULT hr;
DWORD res;

@@ -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());

- hr = MFCreateMediaSession(NULL, &session);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
-
- hr = MFCreateTopologyNode(MF_TOPOLOGY_OUTPUT_NODE, &sink_node);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = MFCreateTopologyNode(MF_TOPOLOGY_SOURCESTREAM_NODE, &src_node);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
-
- hr = MFCreateTopology(&topology);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFTopology_AddNode(topology, sink_node);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFTopology_AddNode(topology, src_node);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFTopologyNode_ConnectOutput(src_node, 0, sink_node, 0);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
-
- hr = IMFMediaSource_CreatePresentationDescriptor(source, &pd);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- hr = IMFPresentationDescriptor_GetStreamDescriptorByIndex(pd, 0, &selected, &sd);
- ok(selected, "got selected %u.\n", !!selected);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- init_source_node(source, -1, src_node, pd, sd);
- IMFTopologyNode_Release(src_node);
- IMFPresentationDescriptor_Release(pd);
- IMFStreamDescriptor_Release(sd);
-
hr = MFCreateMediaType(&output_type);
ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
init_media_type(output_type, video_rgb32_desc, -1);
@@ -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);

- hr = IMFTopologyNode_SetObject(sink_node, (IUnknown *)sink_activate);
- ok(hr == S_OK, "Failed to set object, hr %#lx.\n", hr);
- hr = IMFTopologyNode_SetUINT32(sink_node, &MF_TOPONODE_CONNECT_METHOD, MF_CONNECT_ALLOW_DECODER);
- ok(hr == S_OK, "Failed to set connect method, hr %#lx.\n", hr);
- IMFTopologyNode_Release(sink_node);
-
- hr = IMFTopology_SetUINT32(topology, &MF_TOPOLOGY_ENUMERATE_SOURCE_TYPES, TRUE);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
-
- hr = IMFMediaSession_SetTopology(session, 0, topology);
- ok(hr == S_OK, "Unexpected hr %#lx.\n", hr);
- IMFTopology_Release(topology);
+ create_media_session_with_source_sink(source, sink_activate, &session);

propvar.vt = VT_EMPTY;
hr = IMFMediaSession_Start(session, &GUID_NULL, &propvar);
--
2.45.1

Loading

0 comments on commit 5ead147

Please sign in to comment.