Работа с категориями закрепления
[Функция, связанная с этой страницей DirectShow, является устаревшей функцией. Он был заменен MediaPlayer, IMFMediaEngine, и аудио/ видео захвата в Media Foundation. Эти функции оптимизированы для Windows 10 и Windows 11. Корпорация Майкрософт настоятельно рекомендует использовать в новом коде MediaPlayer, IMFMediaEngine и аудио/видеозахват в Media Foundation вместо DirectShow, когда это возможно. Корпорация Майкрософт предлагает переписать существующий код, в котором используются устаревшие API, чтобы по возможности использовать новые API.]
Для поиска в фильтре закрепления с заданной категорией контактов можно использовать метод ICaptureGraphBuilder2::FindPin . В следующем примере выполняется поиск пин-кода предварительного просмотра видео:
int i = 0;
hr = pBuild->FindPin(
pFilter, // Pointer to a filter to search.
PINDIR_OUTPUT, // Which pin direction?
&PIN_CATEGORY_PREVIEW, // Which category? (NULL means "any category")
&MEDIATYPE_Video, // What media type? (NULL means "any type")
FALSE, // Must be connected?
i, // Get the i'th matching pin (0 = first match)
&pPin // Receives a pointer to the pin.
);
Первый параметр — это указатель на интерфейс фильтра IBaseFilter . Следующие три параметра указывают направление, категорию закрепления и тип носителя. Значение FALSE в пятом параметре указывает, что контакт может быть подключен или не подключен. (Точные определения этих параметров см. в документации по методу.) Если метод находит соответствующий контакт, он возвращает указатель на интерфейс IPin в параметре pPin .
Хотя метод FindPin удобен, при желании можно также написать собственные вспомогательные функции. Чтобы определить категорию пин-кода, вызовите метод IKsPropertySet::Get , как описано в разделе Закрепление набора свойств.
В следующем коде показана вспомогающая функция, которая проверяет, соответствует ли закрепление указанной категории:
// Returns TRUE if a pin matches the specified pin category.
BOOL PinMatchesCategory(IPin *pPin, REFGUID Category)
{
BOOL bFound = FALSE;
IKsPropertySet *pKs = NULL;
HRESULT hr = pPin->QueryInterface(IID_PPV_ARGS(&pKs));
if (SUCCEEDED(hr))
{
GUID PinCategory;
DWORD cbReturned;
hr = pKs->Get(AMPROPSETID_Pin, AMPROPERTY_PIN_CATEGORY, NULL, 0,
&PinCategory, sizeof(GUID), &cbReturned);
if (SUCCEEDED(hr) && (cbReturned == sizeof(GUID)))
{
bFound = (PinCategory == Category);
}
pKs->Release();
}
return bFound;
}
Следующий пример — функция, которая выполняет поиск закрепления по категориям, аналогично методу FindPin :
// Finds the first pin that matches a specified pin category and direction.
HRESULT FindPinByCategory(
IBaseFilter *pFilter, // Pointer to the filter to search.
PIN_DIRECTION PinDir, // Direction of the pin.
REFGUID Category, // Pin category.
IPin **ppPin) // Receives a pointer to the pin.
{
*ppPin = 0;
HRESULT hr = S_OK;
BOOL bFound = FALSE;
IEnumPins *pEnum = 0;
IPin *pPin = 0;
hr = pFilter->EnumPins(&pEnum);
if (FAILED(hr))
{
goto done;
}
while (hr = pEnum->Next(1, &pPin, 0), hr == S_OK)
{
PIN_DIRECTION ThisPinDir;
hr = pPin->QueryDirection(&ThisPinDir);
if (FAILED(hr))
{
goto done;
}
if ((ThisPinDir == PinDir) &&
PinMatchesCategory(pPin, Category))
{
*ppPin = pPin;
(*ppPin)->AddRef(); // The caller must release the interface.
bFound = TRUE;
break;
}
SafeRelease(&pPin);
}
done:
SafeRelease(&pPin);
SafeRelease(&pEnum);
if (SUCCEEDED(hr) && !bFound)
{
hr = E_FAIL;
}
return hr;
}
В следующем коде используется предыдущая функция для поиска закрепления видеопорта в фильтре:
IPin *pVP;
hr = FindPinByCategory(pFilter, PINDIR_OUTPUT,
PIN_CATEGORY_VIDEOPORT, &pVP);
if (SUCCEEDED(hr))
{
// Use pVP ...
// Release when you are done.
pVP->Release();
}
Дополнительные сведения о наборах свойств см. в документации по комплекту драйверов Windows (WDK).
Связанные темы