Module: wine Branch: master Commit: af05ff4b152cf3e3cd4544ffbfa6576a9bd856b6 URL: http://source.winehq.org/git/wine.git/?a=commit;h=af05ff4b152cf3e3cd4544ffbf...
Author: Andrew Eikum aeikum@codeweavers.com Date: Mon May 16 08:28:32 2016 -0500
qcap: Search the whole graph for an unconnected pin.
Signed-off-by: Andrew Eikum aeikum@codeweavers.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/qcap/capturegraph.c | 89 ++++++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 21 deletions(-)
diff --git a/dlls/qcap/capturegraph.c b/dlls/qcap/capturegraph.c index 372e16f..546b1f8 100644 --- a/dlls/qcap/capturegraph.c +++ b/dlls/qcap/capturegraph.c @@ -360,6 +360,66 @@ end: return hr; }
+static HRESULT find_unconnected_pin(CaptureGraphImpl *This, + const GUID *pCategory, const GUID *pType, IUnknown *pSource, IPin **out_pin) +{ + int index = 0; + IPin *source_out; + HRESULT hr; + BOOL usedSmartTeePreviewPin = FALSE; + + /* depth-first search the graph for the first unconnected pin that matches + * the given category and type */ + for(;;){ + IPin *nextpin; + + if (pCategory && (IsEqualIID(pCategory, &PIN_CATEGORY_CAPTURE) || IsEqualIID(pCategory, &PIN_CATEGORY_PREVIEW))){ + IBaseFilter *sourceFilter = NULL; + hr = IUnknown_QueryInterface(pSource, &IID_IBaseFilter, (void**)&sourceFilter); + if (SUCCEEDED(hr)) { + hr = match_smart_tee_pin(This, pCategory, pType, pSource, &source_out); + if (hr == VFW_S_NOPREVIEWPIN) + usedSmartTeePreviewPin = TRUE; + IBaseFilter_Release(sourceFilter); + } else { + hr = ICaptureGraphBuilder2_FindPin(&This->ICaptureGraphBuilder2_iface, pSource, PINDIR_OUTPUT, pCategory, pType, FALSE, index, &source_out); + } + if (FAILED(hr)) + return E_INVALIDARG; + } else { + hr = ICaptureGraphBuilder2_FindPin(&This->ICaptureGraphBuilder2_iface, pSource, PINDIR_OUTPUT, pCategory, pType, FALSE, index, &source_out); + if (FAILED(hr)) + return E_INVALIDARG; + } + + hr = IPin_ConnectedTo(source_out, &nextpin); + if(SUCCEEDED(hr)){ + PIN_INFO info; + + IPin_Release(source_out); + + hr = IPin_QueryPinInfo(nextpin, &info); + if(FAILED(hr) || !info.pFilter){ + WARN("QueryPinInfo failed: %08x\n", hr); + return hr; + } + + hr = find_unconnected_pin(This, pCategory, pType, (IUnknown*)info.pFilter, out_pin); + + IBaseFilter_Release(info.pFilter); + + if(SUCCEEDED(hr)) + return hr; + }else{ + *out_pin = source_out; + if(usedSmartTeePreviewPin) + return VFW_S_NOPREVIEWPIN; + return S_OK; + } + + index++; + } +}
static HRESULT WINAPI fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface, @@ -372,8 +432,7 @@ fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface, CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface); IPin *source_out = NULL, *renderer_in; BOOL rendererNeedsRelease = FALSE; - BOOL usedSmartTeePreviewPin = FALSE; - HRESULT hr; + HRESULT hr, return_hr = S_OK;
FIXME("(%p/%p)->(%s, %s, %p, %p, %p) semi-stub!\n", This, iface, debugstr_guid(pCategory), debugstr_guid(pType), @@ -388,25 +447,13 @@ fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface, if (pCategory && IsEqualIID(pCategory, &PIN_CATEGORY_VBI)) { FIXME("Tee/Sink-to-Sink filter not supported\n"); return E_NOTIMPL; - } else if (pCategory && (IsEqualIID(pCategory, &PIN_CATEGORY_CAPTURE) || IsEqualIID(pCategory, &PIN_CATEGORY_PREVIEW))){ - IBaseFilter *sourceFilter = NULL; - hr = IUnknown_QueryInterface(pSource, &IID_IBaseFilter, (void**)&sourceFilter); - if (SUCCEEDED(hr)) { - hr = match_smart_tee_pin(This, pCategory, pType, pSource, &source_out); - if (hr == VFW_S_NOPREVIEWPIN) - usedSmartTeePreviewPin = TRUE; - IBaseFilter_Release(sourceFilter); - } else { - hr = ICaptureGraphBuilder2_FindPin(iface, pSource, PINDIR_OUTPUT, pCategory, pType, TRUE, 0, &source_out); - } - if (FAILED(hr)) - return E_INVALIDARG; - } else { - hr = ICaptureGraphBuilder2_FindPin(iface, pSource, PINDIR_OUTPUT, pCategory, pType, TRUE, 0, &source_out); - if (FAILED(hr)) - return E_INVALIDARG; }
+ hr = find_unconnected_pin(This, pCategory, pType, pSource, &source_out); + if (FAILED(hr)) + return hr; + return_hr = hr; + if (!pfRenderer) { IEnumMediaTypes *enumMedia = NULL; @@ -480,8 +527,8 @@ fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface, IPin_Release(renderer_in); if (rendererNeedsRelease) IBaseFilter_Release(pfRenderer); - if (SUCCEEDED(hr) && usedSmartTeePreviewPin) - hr = VFW_S_NOPREVIEWPIN; + if (SUCCEEDED(hr)) + return return_hr; return hr; }