Arbeiten mit Anheftkategorien

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde durch MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation ersetzt. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code nach Möglichkeit MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet. Microsoft schlägt vor, vorhandenen Code, der die Legacy-APIs verwendet, um nach Möglichkeit die neuen APIs zu verwenden.]

Um nach einem Filter nach einer Pin mit einer bestimmten Pinkategorie zu suchen, können Sie die ICaptureGraphBuilder2::FindPin-Methode verwenden. Im folgenden Beispiel wird nach einer Videovorschau-Pin gesucht:

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.
);

Der erste Parameter ist ein Zeiger auf die IBaseFilter-Schnittstelle des Filters. Die nächsten drei Parameter geben die Richtung, die Anheftungskategorie und den Medientyp an. Der Wert FALSE im fünften Parameter gibt an, dass der Pin entweder verbunden oder nicht verbunden sein kann. (Die genauen Definitionen dieser Parameter finden Sie in der Dokumentation für die -Methode.) Wenn die Methode einen übereinstimmenden Pin findet, gibt sie einen Zeiger auf die IPin-Schnittstelle im pPin-Parameter zurück.

Obwohl die FindPin-Methode praktisch ist, können Sie auch Ihre eigenen Hilfsfunktionen schreiben, wenn Sie möchten. Um die Kategorie eines Pins zu bestimmen, rufen Sie die IKsPropertySet::Get-Methode auf, wie im Thema Pin Property Set beschrieben.

Der folgende Code zeigt eine Hilfsfunktion, die überprüft, ob eine Pin mit einer angegebenen Kategorie übereinstimmt:

// 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;
}

Das nächste Beispiel ist eine Funktion, die nach einer Anheftung nach Kategorie sucht, ähnlich der FindPin-Methode :

// 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;
}

Der folgende Code verwendet die vorherige Funktion, um nach einem Videoport-Pin für einen Filter zu suchen:

IPin *pVP; 
hr = FindPinByCategory(pFilter, PINDIR_OUTPUT, 
    PIN_CATEGORY_VIDEOPORT, &pVP);
if (SUCCEEDED(hr))
{
    // Use pVP ... 
    // Release when you are done.
    pVP->Release();
}

Weitere Informationen zu Eigenschaftensätzen finden Sie in der Dokumentation zum Windows Driver Kit (WDK).

Themen zur erweiterten Erfassung

Anheften von Eigenschaftensatz

DirectShow Video Capture Filter