Aushandeln von Medientypen

Wenn der Filter Graph Manager die IPin::Verbinden-Methode aufruft, stehen mehrere Optionen zum Angeben eines Medientyps zur Verfügung:

  • Vollständiger Typ: Wenn der Medientyp vollständig angegeben ist, versuchen die Pins, eine Verbindung mit diesem Typ herzustellen. Wenn dies nicht möglich ist, schlägt der Verbindungsversuch fehl.
  • Partieller Medientyp: Ein Medientyp ist partiell, wenn der Haupttyp, Untertyp oder Formattyp GUID _ NULL ist. Der Wert GUID _ NULL fungiert als "Platzhalter", der angibt, dass jeder Wert akzeptabel ist. Die Pins handeln einen Typ aus, der mit dem partiellen Typ konsistent ist.
  • Kein Medientyp: Wenn der Filter Graph Manager einen NULL-Zeiger übergibt, können die Pins jedem Medientyp zustimmen, der für beide Stecknadeln akzeptabel ist.

Wenn die Pins eine Verbindung herstellen, verfügt die Verbindung immer über einen vollständigen Medientyp. Der vom Filter-Manager Graph Medientyp soll die möglichen Verbindungstypen einschränken.

Während des Aushandlungsprozesses schlägt der Ausgabepin einen Medientyp vor, indem er die IPin::ReceiveConnection-Methode des Eingabepins aufruft. Der Eingabepin kann den vorgeschlagenen Typ akzeptieren oder ablehnen. Dieser Vorgang wird wiederholt, bis entweder der Eingabepin einen Typ akzeptiert oder der Ausgabepin keine Typen mehr hat und die Verbindung fehlschlägt.

Wie ein Ausgabepin medientypen auswählt, die vorgeschlagen werden, hängt von der Implementierung ab. In den DirectShow-Basisklassen ruft der Ausgabepin IPin::EnumMediaTypes auf dem Eingabepin auf. Diese Methode gibt einen Enumerator zurück, der die bevorzugten Medientypen des Eingabepins aufzählt. Wenn dies nicht der Fehler ist, werden vom Ausgabepin seine eigenen bevorzugten Typen aufzählt.

Arbeiten mit Medientypen

Überprüfen Sie in jeder Funktion, die einen AM _ MEDIA _ TYPE-Parameter empfängt, immer die Werte von cbFormat und formattype, bevor Sie den pbFormat-Member deferencieren. Der folgende Code ist falsch:

if (pmt->formattype == FORMAT_VideoInfo)
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Wrong!
}

Der folgende Code ist richtig:

if ((pmt->formattype == FORMAT_VideoInfo) && 
    (pmt->cbFormat > sizeof(VIDEOINFOHEADER) &&
    (pbFormat != NULL))
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Now you can dereference pVIH.
}