Поиск несоединяемого закрепления в фильтре
[Функция, связанная с этой страницей, DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngineи аудио и видеозахват в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать новый код MediaPlayer, IMFMediaEngine и аудио-видеозахват в Media Foundation вместо DirectShowпо возможности. Корпорация Майкрософт предлагает, что существующий код, использующий устаревшие API, будет перезаписан для использования новых API, если это возможно.]
В этом разделе описывается, как найти несоединенные закрепление фильтра. Поиск несоединяемого пин-кода полезен при подключении фильтров.
В типичном сценарии построения графа DirectShow требуется несоединяемый пин-код, соответствующий определенному направлению закреплений (входным или выходным данным). Например, при подключении двух фильтров вы подключаете выходной пин-код из одного фильтра к входному закреплению из другого фильтра. Перед подключением оба закрепления должны быть не подключены.
Во-первых, нам нужна функция, которая проверяет, подключен ли пин-код к другому закреплению. Эта функция вызывает метод IPin::ConnectedTo, чтобы проверить, подключен ли пин-код к другому закреплению.
// 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;
}
Заметка
В этом примере используется функция safeRelease для выпуска указателей интерфейса.
Далее нам нужна функция, которая проверяет, соответствует ли пин-код указанному направлению пин-кода. Эта функция вызывает метод IPin::QueryDirection, чтобы получить направление закрепления.
// 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;
}
Следующая функция соответствует закреплению по обоим критериям (направление закрепления и состояние подключения).
// 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;
}
Наконец, следующая функция использует интерфейс IEnumPins для цикла по закреплению фильтра. Вызывающий объект задает нужное направление закреплений. Для каждого закрепления функция вызывает MatchPin
проверить соответствие пин-кода. Если направление совпадает и закрепление не подключено, функция возвращает указатель на соответствующий закрепление в параметре 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;
}
Пример использования этой функции см. в разделе Connect Two Filters.
Связанные разделы