Delen via


Stap 3B. De Methode GetMediaType 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 3B van de zelfstudie Het schrijven van transformatiefilters.

Notitie

Deze stap is niet vereist voor filters die zijn afgeleid van CTransInPlaceFilter.

 

De methode CTransformFilter::GetMediaType retourneert een van de voorkeursuitvoertypen van het filter, waarnaar wordt verwezen door het indexnummer. Deze methode wordt nooit aangeroepen tenzij de invoerpin van het filter al is verbonden. Daarom kunt u het mediatype van de upstream-verbinding gebruiken om de voorkeursuitvoertypen te bepalen.

Een encoder biedt doorgaans één voorkeurstype, dat de doelindeling vertegenwoordigt. Decoders ondersteunen over het algemeen een reeks uitvoerindelingen en bieden ze in volgorde van aflopende kwaliteit of efficiëntie. De lijst kan bijvoorbeeld UYVY, Y211, RGB-24, RGB-565, RGB-555 en RGB-8 zijn, in die volgorde. Effectfilters vereisen mogelijk een exacte overeenkomst tussen de uitvoerindeling en de invoerindeling.

In het volgende voorbeeld wordt één uitvoertype geretourneerd, dat is samengesteld door het invoertype te wijzigen om RLE8-compressie op te geven:

HRESULT CRleFilter::GetMediaType(int iPosition, CMediaType *pMediaType)
{
    ASSERT(m_pInput->IsConnected());
    if (iPosition < 0)
    {
        return E_INVALIDARG;
    }
    if (iPosition == 0)
    {
        HRESULT hr = m_pInput->ConnectionMediaType(pMediaType);
        if (FAILED(hr))
        {
            return hr;
        }
        FOURCCMap fccMap = FCC('MRLE'); 
        pMediaType->subtype = static_cast<GUID>(fccMap);
        pMediaType->SetVariableSize();
        pMediaType->SetTemporalCompression(FALSE);

        ASSERT(pMediaType->formattype == FORMAT_VideoInfo);
        VIDEOINFOHEADER *pVih =
            reinterpret_cast<VIDEOINFOHEADER*>(pMediaType->pbFormat);
        pVih->bmiHeader.biCompression = BI_RLE8;
        pVih->bmiHeader.biSizeImage = DIBSIZE(pVih->bmiHeader); 
        return S_OK;
    }
    // else
    return VFW_S_NO_MORE_ITEMS;
}

In dit voorbeeld roept de methode IPin::ConnectionMediaType aan om het invoertype op te halen uit de invoerpin. Vervolgens worden enkele van de velden gewijzigd om de compressie-indeling aan te geven, als volgt:

  • Er wordt een nieuwe subtype-GUID toegewezen, die is samengesteld uit de FOURCC-code MRLE, met behulp van de klasse FOURCCMap.
  • Hiermee wordt de methode CMediaType::SetVariableSize aangeroepen, waarmee de vlag bFixedSizeSamples wordt ingesteld op FALSE en het lSampleSize element op nul, wat monsters van variabele grootte aangeeft.
  • Hiermee wordt de methode CMediaType::SetTemporalCompression aangeroepen met de waarde FALSE, waarmee wordt aangegeven dat elk frame een sleutelframe is. (Dit veld is alleen informatief, dus u kunt het veld veilig negeren.)
  • Hiermee stelt u het veld biCompression in op BI_RLE8.
  • Hiermee stelt u het veld biSizeImage in op de afbeeldingsgrootte.

Volgende: stap 3C. Implementeer de methode CheckTransform.

DirectShow-filters schrijven