Delen via


Stap 3A. De methode CheckInputType implementeren

[De functie die is gekoppeld aan deze pagina, DirectShow, is een verouderde functie. Het is vervangen door MediaPlayer, IMFMediaEngineen Audio/Video Capture in Media Foundation. Deze functies zijn geoptimaliseerd voor Windows 10 en Windows 11. Microsoft raadt ten zeerste aan om nieuwe code te gebruiken MediaPlayer, IMFMediaEngine en Audio/Video Capture in Media Foundation in plaats van DirectShow, indien mogelijk. Microsoft stelt voor dat bestaande code die gebruikmaakt van de verouderde API's, indien mogelijk opnieuw worden geschreven om de nieuwe API's te gebruiken.]

Dit is stap 3A van de zelfstudie Het schrijven van transformatiefilters.

De methode CTransformFilter::CheckInputType wordt aangeroepen wanneer het upstream-filter een mediatype voorstelt voor het transformatiefilter. Met deze methode wordt een aanwijzer naar een CMediaType--object gebruikt. Dit is een dunne wrapper voor de AM_MEDIA_TYPE structuur. In deze methode moet u elk relevant veld van de AM_MEDIA_TYPE structuur onderzoeken, inclusief de velden in het opmaakblok. U kunt de toegangsmethoden gebruiken die zijn gedefinieerd in CMediaTypeof rechtstreeks verwijzen naar de structuurleden. Als een veld ongeldig is, retourneer dan VFW_E_TYPE_NOT_ACCEPTED. Als het hele mediatype geldig is, retourneer dan S_OK.

In het RLE-encoderfilter moet het invoertype bijvoorbeeld 8-bits of 4-bits niet-gecomprimeerde RGB-video zijn. Er is geen reden om andere invoerindelingen te ondersteunen, zoals 16- of 24-bits RGB, omdat het filter deze naar een lagere bitdiepte moet converteren en DirectShow al een Color Space Converter filter voor dat doel biedt. In het volgende voorbeeld wordt ervan uitgegaan dat de encoder 8-bits video ondersteunt, maar geen 4-bits video:

HRESULT CRleFilter::CheckInputType(const CMediaType *mtIn)
{
    if ((mtIn->majortype != MEDIATYPE_Video) ||
        (mtIn->subtype != MEDIASUBTYPE_RGB8) ||
        (mtIn->formattype != FORMAT_VideoInfo) || 
        (mtIn->cbFormat < sizeof(VIDEOINFOHEADER)))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    VIDEOINFOHEADER *pVih = 
        reinterpret_cast<VIDEOINFOHEADER*>(mtIn->pbFormat);
    if ((pVih->bmiHeader.biBitCount != 8) ||
        (pVih->bmiHeader.biCompression != BI_RGB))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Check the palette table.
    if (pVih->bmiHeader.biClrUsed > PALETTE_ENTRIES(pVih))
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }
    DWORD cbPalette = pVih->bmiHeader.biClrUsed * sizeof(RGBQUAD);
    if (mtIn->cbFormat < sizeof(VIDEOINFOHEADER) + cbPalette)
    {
        return VFW_E_TYPE_NOT_ACCEPTED;
    }

    // Everything is good.
    return S_OK;
}

In dit voorbeeld controleert de methode eerst het primaire type en subtype. Vervolgens wordt het formaattype gecontroleerd om ervoor te zorgen dat het opmaakblok een VIDEOINFOHEADER-structuur is. Het filter kan ook VIDEOINFOHEADER2ondersteunen, maar in dit geval zou er geen echt voordeel zijn. De VIDEOINFOHEADER2 structuur voegt ondersteuning toe voor interlacing en niet-vierkante pixels, die waarschijnlijk niet relevant zijn in 8-bits video.

Als het indelingstype juist is, controleert het voorbeeld de biBitCount en biCompression leden van de structuur VIDEOINFOHEADER om te controleren of de indeling 8-bits niet-gecomprimeerd RGB is. Zoals in dit voorbeeld wordt weergegeven, moet u de

pbFormat

wijs de juiste structuur aan op basis van het indelingstype. Controleer altijd de formattype-GUID (formattype) en de grootte van het formaatblok (cbFormat) voordat u de wijzer cast.

In het voorbeeld wordt ook gecontroleerd of het aantal paletvermeldingen compatibel is met de bitdiepte en het opmaakblok groot genoeg is om de paletvermeldingen vast te houden. Als al deze informatie juist is, retourneert de methode S_OK.

Volgende: stap 3B. Implementeer de Methode GetMediaType.

DirectShow-filters schrijven