Suchen einer nicht verbundenen Stecknadel in einem Filter
In diesem Thema wird beschrieben, wie sie einen nicht verbundenen Pin in einem Filter finden. Das Suchen einer nicht verbundenen Stecknadel ist nützlich, wenn Sie Filter verbinden.
In einem typischen DirectShow-Diagramm-Erstellen-Szenario benötigen Sie einen nicht verbundenen Pin, der einer bestimmten Pinrichtung (Eingabe oder Ausgabe) entspricht. Wenn Sie beispielsweise zwei Filter verbinden, verbinden Sie einen Ausgabepin von einem Filter mit einem Eingabepin aus dem anderen Filter. Beide Stecknadeln müssen nicht verbunden sein, bevor Sie sie verbinden.
Zunächst benötigen wir eine Funktion, die testet, ob eine Stecknadel mit einem anderen Pin verbunden ist. Diese Funktion ruft die IPin::ConnectedTo-Methode auf, um zu testen, ob die Stecknadel mit einem anderen Pin verbunden ist.
// Query whether a pin is connected to another pin.
//
// Note: This function does not return a pointer to the connected pin.
HRESULT IsPinConnected(IPin *pPin, BOOL *pResult)
{
IPin *pTmp = NULL;
HRESULT hr = pPin->ConnectedTo(&pTmp);
if (SUCCEEDED(hr))
{
*pResult = TRUE;
}
else if (hr == VFW_E_NOT_CONNECTED)
{
// The pin is not connected. This is not an error for our purposes.
*pResult = FALSE;
hr = S_OK;
}
SafeRelease(&pTmp);
return hr;
}
Hinweis
In diesem Beispiel wird die SafeRelease-Funktion verwendet, um Schnittstellenzeigener frei zu geben.
Als Nächstes benötigen wir eine Funktion, die testet, ob eine Stecknadel einer angegebenen Stecknadelrichtung entspricht. Diese Funktion ruft die IPin::QueryDirection-Methode auf, um die Pinrichtung zu erhalten.
// Query whether a pin has a specified direction (input / output)
HRESULT IsPinDirection(IPin *pPin, PIN_DIRECTION dir, BOOL *pResult)
{
PIN_DIRECTION pinDir;
HRESULT hr = pPin->QueryDirection(&pinDir);
if (SUCCEEDED(hr))
{
*pResult = (pinDir == dir);
}
return hr;
}
Die nächste Funktion entspricht einem Pin nach beiden Kriterien (Pinrichtung und Verbindungsstatus).
// Match a pin by pin direction and connection state.
HRESULT MatchPin(IPin *pPin, PIN_DIRECTION direction, BOOL bShouldBeConnected, BOOL *pResult)
{
assert(pResult != NULL);
BOOL bMatch = FALSE;
BOOL bIsConnected = FALSE;
HRESULT hr = IsPinConnected(pPin, &bIsConnected);
if (SUCCEEDED(hr))
{
if (bIsConnected == bShouldBeConnected)
{
hr = IsPinDirection(pPin, direction, &bMatch);
}
}
if (SUCCEEDED(hr))
{
*pResult = bMatch;
}
return hr;
}
Schließlich verwendet die folgende Funktion die IEnumPins-Schnittstelle, um die Stecknadeln im Filter zu schleifen. Der Aufrufer gibt die gewünschte Pinrichtung an. Für jeden Pin ruft die Funktion auf, MatchPin um zu testen, ob der Pin eine Übereinstimmung ist. Wenn die Richtung stimmt und die Verbindung des Pins nicht hergestellt ist, gibt die Funktion einen Zeiger auf den entsprechenden Pin im ppPin-Parameter zurück.
// Return the first unconnected input pin or output pin.
HRESULT FindUnconnectedPin(IBaseFilter *pFilter, PIN_DIRECTION PinDir, IPin **ppPin)
{
IEnumPins *pEnum = NULL;
IPin *pPin = NULL;
BOOL bFound = FALSE;
HRESULT hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr))
{
goto done;
}
while (S_OK == pEnum->Next(1, &pPin, NULL))
{
hr = MatchPin(pPin, PinDir, FALSE, &bFound);
if (FAILED(hr))
{
goto done;
}
if (bFound)
{
*ppPin = pPin;
(*ppPin)->AddRef();
break;
}
SafeRelease(&pPin);
}
if (!bFound)
{
hr = VFW_E_NOT_FOUND;
}
done:
SafeRelease(&pPin);
SafeRelease(&pEnum);
return hr;
}
Ein Beispiel für die Verwendung dieser Funktion finden Sie unter Verbinden Zwei Filter.