Buscar un pin no conectado en un filtro
[La característica asociada a esta página, DirectShow, es una característica heredada. Se ha reemplazado por MediaPlayer, IMFMediaEngine y Captura de audio/vídeo en Media Foundation. Esas características se han optimizado para Windows 10 y Windows 11. Microsoft recomienda encarecidamente que el nuevo código use MediaPlayer, IMFMediaEngine y Audio/Video Capture en Media Foundation en lugar de DirectShow, siempre que sea posible. Microsoft sugiere que el código existente que usa las API heredadas se reescriba para usar las nuevas API si es posible.
En este tema se describe cómo buscar una patilla no conectada en un filtro. La búsqueda de un pin no conectado es útil cuando se conectan filtros.
En un escenario típico de creación de grafos de DirectShow, necesita un pin no conectado que coincida con una dirección de patilla determinada (entrada o salida). Por ejemplo, al conectar dos filtros, se conecta un pin de salida de un filtro a un pin de entrada desde el otro filtro. Ambos pines deben estar desconectados antes de conectarlos.
En primer lugar, necesitamos una función que compruebe si un pin está conectado a otro pin. Esta función llama al método IPin::ConnectedTo para comprobar si el pin está conectado a otro pin.
// 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;
}
Nota:
En este ejemplo se usa la función SafeRelease para liberar punteros de interfaz.
A continuación, necesitamos una función que compruebe si una patilla coincide con una dirección de patilla especificada. Esta función llama al método IPin::QueryDirection para obtener la dirección del pin.
// 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 siguiente función coincide con un pin por ambos criterios (dirección de patilla y estado de conexión).
// 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;
}
Por último, la siguiente función usa la interfaz IEnumPins para recorrer en bucle las patillas del filtro. El autor de la llamada especifica la dirección de patilla deseada. Para cada patilla, la función llama MatchPin
a para comprobar si el pin es una coincidencia. Si la dirección coincide y la patilla no está conectada, la función devuelve un puntero al pin coincidente en el parámetro 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;
}
Para obtener un ejemplo de cómo se puede usar esta función, vea Conectar dos filtros.
Temas relacionados