Работа с категориями закрепляемых элементов
[Функция, связанная с этой страницей, 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) .
Связанные разделы