[PATCH 3/5] strmbase/transform: Check whether the source is connected in TransformFilter_Input_Receive().

Zebediah Figura z.figura12 at gmail.com
Fri Nov 22 21:14:01 CST 2019

Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
The goal is essentially to get rid of BaseOutputPinImpl_Deliver(). This function
is mostly a wrapper around IMemInputPin::Receive(), but which also takes the
filter lock while checking if the pin is connected.

This is not particularly necessary, according to DirectShow conventions: a
filter should only receive data while the graph is running, and pins cannot be
connected or disconnected while the graph is running. Even in the case of
dynamic reconnection, the DirectX SDK documentation specifies that the upstream
filter should be manually prevented (or prevent itself) from delivering samples.

Besides this, taking the filter lock in the streaming thread can lead to
temporary or permanent deadlock. We currently wait in IMediaFilter::GetState()
while holding the filter lock, and the SDK documentation states that methods
such as IMediaFilter::Stop() and IPin::BeginFlush() should hold the filter lock
while waiting for the streaming thread to complete. One can conclude from this
that the filter lock should never be taken from the streaming thread.

 dlls/strmbase/transform.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/dlls/strmbase/transform.c b/dlls/strmbase/transform.c
index e7d4d66164..29c385793a 100644
--- a/dlls/strmbase/transform.c
+++ b/dlls/strmbase/transform.c
@@ -59,6 +59,16 @@ static HRESULT WINAPI TransformFilter_Input_Receive(struct strmbase_sink *This,
     TRACE("%p\n", This);
+    /* We do not expect pin connection state to change while the filter is
+     * running. This guarantee is necessary, since otherwise we would have to
+     * take the filter lock, and we can't take the filter lock from a streaming
+     * thread. */
+    if (!pTransform->source.pMemInputPin)
+    {
+        WARN("Source is not connected, returning VFW_E_NOT_CONNECTED.\n");
+        return VFW_E_NOT_CONNECTED;
+    }
     if (pTransform->filter.state == State_Stopped)

More information about the wine-devel mailing list