Rechercher une épingle non connectée sur un filtre
[La fonctionnalité associée à cette page, DirectShow, est une fonctionnalité héritée. Il a été remplacé par MediaPlayer, IMFMediaEngineet audio/vidéo capture dans Media Foundation. Ces fonctionnalités ont été optimisées pour Windows 10 et Windows 11. Microsoft recommande vivement que le nouveau code utilise MediaPlayer, IMFMediaEngine et capture audio/vidéo dans Media Foundation au lieu de directShow, lorsque cela est possible. Microsoft suggère que le code existant qui utilise les API héritées soit réécrit pour utiliser les nouvelles API si possible.]
Cette rubrique explique comment rechercher une broche non connectée sur un filtre. La recherche d’une broche non connectée est utile lorsque vous connectez des filtres.
Dans un scénario classique de création de graphiques DirectShow, vous avez besoin d’une broche non connectée qui correspond à une direction particulière (entrée ou sortie). Par exemple, lorsque vous connectez deux filtres, vous connectez une broche de sortie d’un filtre à une broche d’entrée à partir de l’autre filtre. Les deux broches doivent être non connectées avant de les connecter.
Tout d’abord, nous avons besoin d’une fonction qui teste si une broche est connectée à une autre broche. Cette fonction appelle la méthode IPin ::ConnectedTo pour tester si la broche est connectée à une autre broche.
// 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;
}
Note
Cet exemple utilise la fonction SafeRelease pour libérer des pointeurs d’interface.
Ensuite, nous avons besoin d’une fonction qui teste si une broche correspond à une direction de broche spécifiée. Cette fonction appelle la méthode IPin ::QueryDirection pour obtenir le sens de l’épingle.
// 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;
}
La fonction suivante correspond à une broche par les deux critères (direction de l’épingle et état de connexion).
// 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;
}
Enfin, la fonction suivante utilise l’interface IEnumPins pour parcourir les broches du filtre. L’appelant spécifie la direction de l’épingle souhaitée. Pour chaque broche, la fonction appelle MatchPin
pour tester si la broche est une correspondance. Si la direction correspond et que la broche n’est pas connectée, la fonction retourne un pointeur vers la broche correspondante dans le paramètre ppPin.
// 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;
}
Pour obtenir un exemple de la façon dont cette fonction peut être utilisée, consultez Connecter deux filtres.
Rubriques connexes