[PATCH] quartz: Enumerate all the pins on filter and check directions when rendering.

Lei Zhang thestig at google.com
Mon Dec 15 17:40:23 CST 2008


Hi,

When rendering the filter graph, we have a filter with an output pin,
and we need to look for candidate filters with input pins to connect
to.

Right now, for each candidate filter, we just look at the first pin
and try to connect to it. There's no guarantee we'll enumerate the
input pin on the filter first. We might get the output filter, which
won't work. Instead we should enumerate all the pins on the candidate
filter, and only try to connect to the input pins.
-------------- next part --------------
From ec66704df348e634727dea47b2b4c8ac9666216d Mon Sep 17 00:00:00 2001
From: Lei Zhang <thestig at google.com>
Date: Mon, 15 Dec 2008 15:31:43 -0800
Subject: [PATCH] quartz: Enumerate all the pins on filter and check directions when rendering.

---
 dlls/quartz/filtergraph.c |   75 ++++++++++++++++++++++++++++----------------
 1 files changed, 48 insertions(+), 27 deletions(-)

diff --git a/dlls/quartz/filtergraph.c b/dlls/quartz/filtergraph.c
index 8480d25..967a578 100644
--- a/dlls/quartz/filtergraph.c
+++ b/dlls/quartz/filtergraph.c
@@ -1318,7 +1318,7 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
             GUID clsid;
             IPin* ppinfilter;
             IBaseFilter* pfilter = NULL;
-            IEnumPins* penumpins;
+            IEnumPins* penumpins = NULL;
             ULONG pin;
 
             hr = GetFilterInfo(pMoniker, &clsid, &var);
@@ -1348,40 +1348,61 @@ static HRESULT WINAPI FilterGraph2_Render(IFilterGraph2 *iface, IPin *ppinOut)
                 WARN("Splitter Enumpins (%x)\n", hr);
                 goto error;
             }
-            hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin);
-            IEnumPins_Release(penumpins);
-            if (FAILED(hr)) {
-                WARN("Next (%x)\n", hr);
-                goto error;
-            }
-            if (pin == 0) {
-                WARN("No Pin\n");
-                hr = E_FAIL;
-                goto error;
-            }
 
-            /* Connect the pin to the "Renderer" */
-            hr = IPin_Connect(ppinOut, ppinfilter, NULL);
-            IPin_Release(ppinfilter);
+            while ((hr = IEnumPins_Next(penumpins, 1, &ppinfilter, &pin)) == S_OK)
+            {
+                PIN_DIRECTION dir;
 
-            if (FAILED(hr)) {
-                WARN("Unable to connect %s to renderer (%x)\n", debugstr_w(V_UNION(&var, bstrVal)), hr);
-                goto error;
-            }
-            TRACE("Connected, recursing %s\n",  debugstr_w(V_UNION(&var, bstrVal)));
+                if (pin == 0) {
+                    WARN("No Pin\n");
+                    hr = E_FAIL;
+                    goto error;
+                }
 
-            VariantClear(&var);
+                hr = IPin_QueryDirection(ppinfilter, &dir);
+                if (FAILED(hr)) {
+                    IPin_Release(ppinfilter);
+                    WARN("QueryDirection failed (%x)\n", hr);
+                    goto error;
+                }
+                if (dir != PINDIR_INPUT) {
+                    IPin_Release(ppinfilter);
+                    continue; /* Wrong direction */
+                }
 
-            hr = FilterGraph2_RenderRecurse(This, ppinfilter);
-            if (FAILED(hr)) {
-                WARN("Unable to connect recursively (%x)\n", hr);
-                goto error;
+                /* Connect the pin to the "Renderer" */
+                hr = IPin_Connect(ppinOut, ppinfilter, NULL);
+                IPin_Release(ppinfilter);
+
+                if (FAILED(hr)) {
+                    WARN("Unable to connect %s to renderer (%x)\n", debugstr_w(V_UNION(&var, bstrVal)), hr);
+                    goto error;
+                }
+                TRACE("Connected, recursing %s\n",  debugstr_w(V_UNION(&var, bstrVal)));
+
+                VariantClear(&var);
+
+                hr = FilterGraph2_RenderRecurse(This, ppinfilter);
+                if (FAILED(hr)) {
+                    WARN("Unable to connect recursively (%x)\n", hr);
+                    goto error;
+                }
+                IBaseFilter_Release(pfilter);
+                break;
+            }
+            if (SUCCEEDED(hr)) {
+                IEnumPins_Release(penumpins);
+                break; /* out of IEnumMoniker_Next loop */
             }
-            IBaseFilter_Release(pfilter);
-            break;
+
+            /* IEnumPins_Next failed, all other failure case caught by goto error */
+            WARN("IEnumPins_Next (%x)\n", hr);
+            /* goto error */
 
 error:
             VariantClear(&var);
+            if (penumpins)
+                IEnumPins_Release(penumpins);
             if (pfilter) {
                 IFilterGraph2_RemoveFilter(iface, pfilter);
                 IBaseFilter_Release(pfilter);
-- 
1.5.4.5


More information about the wine-patches mailing list