Freigeben über


Schritt 3C. Implementieren der CheckTransform-Methode

[Das dieser Seite zugeordnete Feature DirectShow ist ein Legacyfeature. Es wurde von MediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation abgelöst. Diese Features wurden für Windows 10 und Windows 11 optimiert. Microsoft empfiehlt dringend, dass neuer Code mediaPlayer, IMFMediaEngine und Audio/Video Capture in Media Foundation anstelle von DirectShow verwendet, wenn möglich. Microsoft schlägt vor, dass vorhandener Code, der die Legacy-APIs verwendet, so umgeschrieben wird, dass nach Möglichkeit die neuen APIs verwendet werden.]

Dies ist Schritt 3C des Tutorials Schreiben von Transformationsfiltern.

Hinweis

Dieser Schritt ist für Filter, die von CTransInPlaceFilter abgeleitet werden, nicht erforderlich.

 

Die CTransformFilter::CheckTransform-Methode überprüft, ob ein vorgeschlagener Ausgabetyp mit dem aktuellen Eingabetyp kompatibel ist. Die -Methode wird auch aufgerufen, wenn der Eingabestift nach der Verbindung des Ausgabepins wieder verbunden wird.

Im folgenden Beispiel wird überprüft, ob das Format RLE8-Video ist. Die Bildabmessungen stimmen mit dem Eingabeformat überein; und die Paletteneinträge sind identisch. Außerdem werden Quell- und Zielrechtecke abgelehnt, die nicht der Bildgröße entsprechen.

HRESULT CRleFilter::CheckTransform(
    const CMediaType *mtIn, const CMediaType *mtOut)
{
    // Check the major type.
    if (mtOut->majortype != MEDIATYPE_Video)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Check the subtype and format type.
    FOURCCMap fccMap = FCC('MRLE'); 
    if (mtOut->subtype != static_cast<GUID>(fccMap))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if ((mtOut->formattype != FORMAT_VideoInfo) || 
        (mtOut->cbFormat < sizeof(VIDEOINFOHEADER)))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Compare the bitmap information against the input type.
    ASSERT(mtIn->formattype == FORMAT_VideoInfo);
    BITMAPINFOHEADER *pBmiOut = HEADER(mtOut->pbFormat);
    BITMAPINFOHEADER *pBmiIn = HEADER(mtIn->pbFormat);
    if ((pBmiOut->biPlanes != 1) ||
        (pBmiOut->biBitCount != 8) ||
        (pBmiOut->biCompression != BI_RLE8) ||
        (pBmiOut->biWidth != pBmiIn->biWidth) ||
        (pBmiOut->biHeight != pBmiIn->biHeight))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Compare source and target rectangles.
    RECT rcImg;
    SetRect(&rcImg, 0, 0, pBmiIn->biWidth, pBmiIn->biHeight);
    RECT *prcSrc = &((VIDEOINFOHEADER*)(mtIn->pbFormat))->rcSource;
    RECT *prcTarget = &((VIDEOINFOHEADER*)(mtOut->pbFormat))->rcTarget;
    if (!IsRectEmpty(prcSrc) && !EqualRect(prcSrc, &rcImg))
    {
        return VFW_E_INVALIDMEDIATYPE;
    }
    if (!IsRectEmpty(prcTarget) && !EqualRect(prcTarget, &rcImg))
    {
        return VFW_E_INVALIDMEDIATYPE;
    }

    // Check the palette table.
    if (pBmiOut->biClrUsed != pBmiIn->biClrUsed)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    DWORD cbPalette = pBmiOut->biClrUsed * sizeof(RGBQUAD);
    if (mtOut->cbFormat < sizeof(VIDEOINFOHEADER) + cbPalette)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    if (0 != memcmp(pBmiOut + 1, pBmiIn + 1, cbPalette))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Everything is good.
    return S_OK;
}

Erneute Verbindungen anheften

Anwendungen können Pins trennen und erneut verbinden. Angenommen, eine Anwendung verbindet beide Pins, trennt den Eingabenadel und verbindet dann den Eingabestift mithilfe einer neuen Bildgröße erneut. In diesem Fall schlägt CheckTransform fehl, da die Abmessungen des Bilds nicht mehr übereinstimmen. Dieses Verhalten ist sinnvoll, obwohl der Filter auch versuchen könnte, den Ausgabepin mit einem neuen Medientyp wiederherzustellen.

Weiter: Schritt 4. Legen Sie Zuweisungseigenschaften fest.

Erneutes Verbinden von Pins

Quell- und Zielrechtecke in Videorenderern

Schreiben von DirectShow-Filtern