Unterstützung dynamischer Formatänderungen in AVStream-Codecs
Wenn eine dynamische Formatänderung in einem ausgeführten Mediendatenstrom auftritt, verhandelt das vom System bereitgestellte Devproxy-Modul mit dem Aufnahmepin, um zu bestimmen, ob das neue Format akzeptabel ist.
Die folgende Abfolge von Ereignissen tritt auf, wenn eine dynamische Formatänderung von der Medienquelle stammt:
Der Treiber empfängt eine KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT Anforderung, um zu bestimmen, ob der Eingabe-KS-Pin den neuen Medientyp unterstützt. Treiber müssen diese Eigenschaft unterstützen.
Wenn der Eingabenadel den neuen Medientyp unterstützt, sollte der KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT-Handler STATUS_SUCCESS zurückgeben. Der Treiber bestimmt dann, ob er den Stream fortsetzen kann, indem er die vorgeschlagene Eingabe zusammen mit den aktuell ausgewählten Ausgabemedientypen verwendet. Wenn ja, wird der Stream fortgesetzt.
Wenn der Eingabenadel den neu vorgeschlagenen Medientyp nicht unterstützt, sollte der KSPROPERTY_CONNECTION_PROPOSEDATAFORMAT-Handler einen Fehler zurückgeben. Der HW MFT verhandelt dann den Medientyp mit der verbundenen Komponente neu.
Wenn der Eingabenadel den neuen Medieneingabetyp unterstützt, der KS-Filter jedoch einen anderen Ausgabemedientyp erfordert, sollte der Treiber wie weiter unten in diesem Thema beschrieben ein KSEVENT_DYNAMIC_FORMAT_CHANGE-Ereignis generieren, um den HW MFT über die Änderung des Medientyps zu informieren.
Wenn die HW MFT die KSEVENT-Benachrichtigung empfängt, übergibt sie den Ausgabepin von KSSTATE_RUN zu KSSTATE_STOP.
Der HW MFT fragt dann den Treiber nach verfügbaren Medientypen ab, was sich in einen Aufruf des AVStrMiniIntersectHandlerEx-Schnitthandlers des Treibers übersetzt. Der Treiber sollte bevorzugte Ausgabemedientypen in der Reihenfolge der Präferenz melden.
Der Benutzermodusclient wählt einen Medientyp aus und legt den neuen Medientyp am Ausgabepin des HW MFT fest. Dies führt zu einem Aufruf der AVStrMiniPinSetDataFormat-Dispatchroutine des Treibers. Wenn der Treiber das Format akzeptiert, indem er STATUS_SUCCESS zurückgibt, wird das Streaming mit dem neuen Medientyp fortgesetzt. Wenn der Aufruf fehlschlägt, müssen die an der Formatänderung beteiligten Komponenten den Medientyp neu aushandeln.
Der HW MFT überprüft, ob sich das verbundene Medium ändert. Wenn keine Änderung erfolgt, wird der ausgewählte Medientyp auf der Pin festgelegt und in KSSTATE_RUN. Wenn sich das verbundene Medium ändert, zerstört das HW MFT den Pin und erstellt ihn mit dem neu ausgewählten Medientyp und Medium neu. Der MFT setzt den Stift dann in KSSTATE_RUN.
Streaming-Fortsetzungen.
In bestimmten Situationen erkennt eine Medienquelle möglicherweise keine Formatänderung. Beispielsweise müsste ein MPEG2-Decoder jedes Paket decodieren, um eine Formatänderung zu finden.
Wenn der Treiber in einem solchen Fall eine Formatänderung erkennt, sollte der Hardwaretreiber eine dynamische Formatänderung KSEVENT generieren. Der HW MFT fragt dann den Pin nach den unterstützten Medientypen ab. Der Pin sollte die bevorzugten Medientypen in der Reihenfolge der Einstellung zurückgeben. Der HW MFT folgt dann der Sequenz von Ereignissen, die in den Schritten 4 bis 9 des vorherigen Abschnitts beschrieben wurden.
Wenn der Treiber eine solche Formatänderung nicht verarbeiten kann, sollte er einen Streamingfehler zurückgeben, der dann an MF weitergegeben wird.
Im folgenden Codebeispiel wird gezeigt, wie Sie eine neue dynamische Formatänderung mithilfe eines KSEVENT definieren:
// {162AC456-83D7-4239-96DF-C75FFA138BC6}
#define STATIC_KSEVENTSETID_DynamicFormatChange\
0x162ac456, 0x83d7, 0x4239, 0x96, 0xdf, 0xc7, 0x5f, 0xfa, 0x13, 0x8b, 0xc6 DEFINE_GUIDSTRUCT("162AC456-83D7-4239-96DF-C75FFA138BC6", KSEVENTSETID_ DynamicFormatChange);
#define KSEVENTSETID_DynamicFormatChange DEFINE_GUIDNAMED(KSEVENTSETID_ DynamicFormatChange)
typedef enum {
KSEVENT_DYNAMIC_FORMAT_CHANGE = 0
};
DEFINE_KSEVENT_TABLE(DynamicFormatChangeEventTable) {
DEFINE_KSEVENT_ITEM
(
KSEVENT_DYNAMIC_FORMAT_CHANGE,
sizeof(KSEVENTDATA),
0,
NULL,
NULL,
NULL
)
};
KSEVENT_SET PinEventTable[] =
{
DEFINE_KSEVENT_SET
(
&KSEVENTSETID_DynamicFormatChange,
SIZEOF_ARRAY(DynamicFormatChangeEventTable),
DynamicFormatChangeEventTable
)
};
Jeder Pin sollte dieses Ereignis in seinem Pindeskriptor verfügbar machen. Das Ereignis ist vom Typ KSEVENTF_EVENT_HANDLE.
Bevor der Treiber dieses Ereignis generiert, sollte er die bevorzugten Medientypen für den KS-Pin basierend auf dem aktuell ausgewählten Eingabemedientyp festlegen. Dazu können Sie die funktion _KsEdit auf dem Deskriptor des Pins verwenden.
Um das Ereignis zu generieren, sollten Treiber KsGenerateEvents aufrufen.