Bagikan melalui


Menemukan Pin Yang Tidak Tersambung pada Filter

[Fitur yang terkait dengan halaman ini, DirectShow, adalah fitur warisan. Ini telah digantikan oleh MediaPlayer, IMFMediaEngine, dan Tangkapan Audio/Video di Media Foundation. Fitur-fitur tersebut telah dioptimalkan untuk Windows 10 dan Windows 11. Microsoft sangat menyarankan agar kode baru menggunakan MediaPlayer, IMFMediaEngine dan Audio/Video Capture di Media Foundation alih-alih DirectShow, jika memungkinkan. Microsoft menyarankan agar kode yang ada yang menggunakan API warisan ditulis ulang untuk menggunakan API baru jika memungkinkan.]

Topik ini menjelaskan cara menemukan pin yang tidak tersambung pada filter. Menemukan pin yang tidak tersambung berguna saat Anda menyambungkan filter.

Dalam skenario pembuatan grafik DirectShow yang khas, Anda memerlukan pin yang tidak terhubung yang cocok dengan arah pin tertentu (input atau output). Misalnya, saat Anda menyambungkan dua filter, Anda menyambungkan pin output dari satu filter ke pin input dari filter lain. Kedua pin harus tidak tersambung sebelum Anda menyambungkannya.

Pertama, kita memerlukan fungsi yang menguji apakah pin terhubung ke pin lain. Fungsi ini memanggil metode IPin::ConnectedTo untuk menguji apakah pin tersambung ke pin lain.

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

Catatan

Contoh ini menggunakan fungsi SafeRelease untuk merilis pointer antarmuka.

 

Selanjutnya, kita memerlukan fungsi yang menguji apakah pin cocok dengan arah pin tertentu. Fungsi ini memanggil metode IPin::QueryDirection untuk mendapatkan arah pin.

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

Fungsi berikutnya cocok dengan pin berdasarkan kedua kriteria (arah pin dan status koneksi).

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

Terakhir, fungsi berikut menggunakan antarmuka IEnumPins untuk mengulangi pin pada filter. Penelepon menentukan arah pin yang diinginkan. Untuk setiap pin, fungsi memanggil MatchPin untuk menguji apakah pin cocok. Jika arah cocok dan pin tidak tersambung, fungsi mengembalikan penunjuk ke pin yang cocok dalam parameter 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;
}

Untuk contoh bagaimana fungsi ini dapat digunakan, lihat Menyambungkan Dua Filter.

Menghitung Pin

Teknik Graph-Building Umum

ICaptureGraphBuilder2::FindPin