Freigeben über


Implementieren einer Vorschaunadel (optional)

[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.]

In diesem Thema wird beschrieben, wie Sie eine Vorschaunadel für einen DirectShow-Erfassungsfilter implementieren.

Wenn Ihr Filter über einen Vorschaupin verfügt, muss der Vorschaupin eine Kopie der vom Erfassungspin übermittelten Daten senden. Wenn Sie nur Daten vom Vorschaupin senden, führt dies nicht dazu, dass der Erfassungspin Frames ablöscht. Der Erfassungspin hat immer Vorrang vor dem Vorschaupin.

Der Erfassungspin und der Vorschaupin müssen Daten im gleichen Format senden. Daher müssen sie eine Verbindung mit identischen Medientypen herstellen. Wenn der Erfassungspin zuerst eine Verbindung herstellt, sollte der Vorschaupin denselben Medientyp bieten und alle anderen Typen ablehnen. Wenn der Vorschaupin zuerst eine Verbindung herstellt und der Erfassungspin eine Verbindung mit einem anderen Medientyp herstellt, sollte der Vorschaupin mithilfe des neuen Medientyps erneut verbunden werden. Wenn der Filter nach dem Vorschaupin den neuen Typ ablehnt, sollte der Erfassungspin auch den Typ ablehnen. Verwenden Sie die IPin::QueryAccept-Methode , um den Nachgeschalteten Filter über den Vorschaupin abzufragen, und verwenden Sie die IFilterGraph::Reconnect-Methode , um den Pin wiederherzustellen. Diese Regeln gelten auch, wenn der Filter Graph-Manager den Erfassungspin erneut verbindet.

Das folgende Beispiel zeigt eine Gliederung dieses Prozesses:

// Override CBasePin::CheckMediaType.
CCapturePin::CheckMediaType(CMediaType *pmt)
{
    if (m_pMyPreviewPin->IsConnected()) 
    {
        // The preview pin is already connected, so query the pin it is
        // connected to. If the other pin rejects it, so do we.
        hr = m_pMyPreviewPin->GetConnected()->QueryAccept(pmt);
        if (hr != S_OK) 
        {
            // The preview pin cannot reconnect with this media type.
            return E_INVALIDARG;
        }
        // The preview pin will reconnect when SetMediaType is called.
    }
    // Decide whether the capture pin accepts the format. 
    BOOL fAcceptThisType = ...  // (Not shown.)
    return (fAcceptThisType? S_OK : E_FAIL);
}

// Override CBasePin::SetMediaType.
CCapturePin::SetMediaType(CMediaType *pmt);
{
    if (m_pMyPreviewPin->IsConnected()) 
    {
        // The preview pin is already connected, so it must reconnect.
        if (m_pMyPreviewPin->GetConnected()->QueryAccept(pmt) == S_OK)
        {
            // The downstream pin will accept the new type, so it's safe
            // to reconnect. 
            m_pFilter->m_pGraph->Reconnect(m_pMyPreviewPin);
        }
        else
        {
            return VFW_E_INVALIDMEDIATYPE;
        }
    }
    // Now do anything that the capture pin needs to set the type.
    hr = MyInternalSetMediaType(pmt);

    // And finally, call the base-class method.
    return CBasePin::SetMediaType(pmt);
}

CPreviewPin::CheckMediaType(CMediaType *pmt)
{
    if (m_pMyCapturePin->IsConnected())
    {
       // The preview pin must connect with the same type.
       CMediaType cmt = m_pMyCapturePin->m_mt;
       return (*pmt == cmt ? S_OK : VFW_E_INVALIDMEDIATYPE);
    }
    // Decide whether the preview pin accepts the format. You can use your 
    // knowledge of which types the capture pin will accept. Regardless,
    // when the capture pin connects, the preview pin will reconnect.
    return (fAcceptThisType? S_OK : E_FAIL);
}

Herstellen einer Verbindung mit Filtern

Schreiben von Erfassungsfiltern