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>
This commit is contained in:
parent
65bab6a5fe
commit
af05ff4b15
|
@ -360,6 +360,66 @@ end:
|
||||||
return hr;
|
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
|
static HRESULT WINAPI
|
||||||
fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface,
|
fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface,
|
||||||
|
@ -372,8 +432,7 @@ fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface,
|
||||||
CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
|
CaptureGraphImpl *This = impl_from_ICaptureGraphBuilder2(iface);
|
||||||
IPin *source_out = NULL, *renderer_in;
|
IPin *source_out = NULL, *renderer_in;
|
||||||
BOOL rendererNeedsRelease = FALSE;
|
BOOL rendererNeedsRelease = FALSE;
|
||||||
BOOL usedSmartTeePreviewPin = FALSE;
|
HRESULT hr, return_hr = S_OK;
|
||||||
HRESULT hr;
|
|
||||||
|
|
||||||
FIXME("(%p/%p)->(%s, %s, %p, %p, %p) semi-stub!\n", This, iface,
|
FIXME("(%p/%p)->(%s, %s, %p, %p, %p) semi-stub!\n", This, iface,
|
||||||
debugstr_guid(pCategory), debugstr_guid(pType),
|
debugstr_guid(pCategory), debugstr_guid(pType),
|
||||||
|
@ -388,25 +447,13 @@ fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface,
|
||||||
if (pCategory && IsEqualIID(pCategory, &PIN_CATEGORY_VBI)) {
|
if (pCategory && IsEqualIID(pCategory, &PIN_CATEGORY_VBI)) {
|
||||||
FIXME("Tee/Sink-to-Sink filter not supported\n");
|
FIXME("Tee/Sink-to-Sink filter not supported\n");
|
||||||
return E_NOTIMPL;
|
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)
|
if (!pfRenderer)
|
||||||
{
|
{
|
||||||
IEnumMediaTypes *enumMedia = NULL;
|
IEnumMediaTypes *enumMedia = NULL;
|
||||||
|
@ -480,8 +527,8 @@ fnCaptureGraphBuilder2_RenderStream(ICaptureGraphBuilder2 * iface,
|
||||||
IPin_Release(renderer_in);
|
IPin_Release(renderer_in);
|
||||||
if (rendererNeedsRelease)
|
if (rendererNeedsRelease)
|
||||||
IBaseFilter_Release(pfRenderer);
|
IBaseFilter_Release(pfRenderer);
|
||||||
if (SUCCEEDED(hr) && usedSmartTeePreviewPin)
|
if (SUCCEEDED(hr))
|
||||||
hr = VFW_S_NOPREVIEWPIN;
|
return return_hr;
|
||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue