フィルターで接続されていないピンを検索する

[このページに関連付けられている機能 DirectShow は、従来の機能です。 MediaPlayer、IMFMediaEngine、Media Foundation のオーディオ/ビデオ キャプチャに置き換わりました。 これらの機能は、Windows 10とWindows 11用に最適化されています。 新しいコードでは、可能であれば、DirectShow ではなく Media Foundation で MediaPlayerIMFMediaEngineAudio/Video Capture を使用することを強くお勧めします。 Microsoft は、レガシ API を使用する既存のコードを、可能であれば新しい API を使用するように書き換えるよう提案しています。]

このトピックでは、フィルターで接続されていないピンを検索する方法について説明します。 接続されていないピンを見つけることは、フィルターを接続する場合に便利です。

一般的な DirectShow グラフ構築シナリオでは、特定のピンの方向 (入力または出力) に一致する接続されていないピンが必要です。 たとえば、2 つのフィルターを接続する場合、出力ピンを 1 つのフィルターからもう一方のフィルターの入力ピンに接続します。 両方のピンを接続する前に、接続されていない必要があります。

まず、ピンが別のピンに接続されているかどうかをテストする関数が必要です。 この関数は 、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;
}

この関数の使用方法の例については、「 2 つのフィルターを接続する」を参照してください。

ピンの列挙

一般的なGraph-Building手法

ICaptureGraphBuilder2::FindPin