Verwenden von IAMVideoAccelerator durch Decoder
[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.]
Die IAMVideoAccelerator-Schnittstelle ermöglicht generische Videobeschleunigungsvorgänge, einschließlich DirectX-Videobeschleunigung (VA). Für die Nicht-DirectX VA-Beschleunigung müssen Decoder und Videotreiber einem gemeinsamen Protokoll entsprechen.
In diesem Abschnitt wird die allgemeine Reihenfolge der Vorgänge beschrieben, die jeder Decoder bei verwendung dieser Schnittstelle befolgen sollte. Weitere Spezifische Informationen zu DirectX VA-basierten Decodern finden Sie unter Zuordnen der DirectX-Videobeschleunigung zu IAMVideoAccelerator.
Hinweis
Diese Schnittstelle ist in Windows 2000 und höher verfügbar.
Die IAMVideoAccelerator-Schnittstelle wird am Eingabestift des Overlay Mixers oder des Video Mixing Renderers (VMR) verfügbar gemacht. Die IAMVideoAcceleratorNotify-Schnittstelle wird am Ausgabepin des Decoders verfügbar gemacht. Die Abfolge von Ereignissen zum Verbinden der Filterpins sieht wie folgt aus:
Der Filter Graph-Manager ruft IPin::Connect am Ausgabepin des Decoderfilters auf. Ein AM_MEDIA_TYPE ist ein optionaler Parameter.
- AM_MEDIA_TYPE ist eine Datenstruktur, die einen Medientyp beschreibt. Es enthält eine Haupttyp-GUID (die in unserem Fall MEDIATYPE_Video sein sollte), eine Untertyp-GUID (die in unserem Fall eine Videobeschleunigungs-GUID sein sollte) und eine Vielzahl anderer Dinge. Eines dieser Elemente ist eine Formattyp-GUID, die Informationen über die Medien enthält, einschließlich in unserem Fall die Breite und Höhe eines nicht komprimierten Videobilds, höchstwahrscheinlich in einer MPEG1VIDEOINFO-, VIDEOINFOHEADER-, MPEG2VIDEOINFO- oder VIDEOINFOHEADER2-Struktur .
- Die AM_MEDIA_TYPE-Struktur weist den Decoder an, mit dem angegebenen Medientyp zu arbeiten, der "vollständig" oder "teilweise angegeben" sein kann. Wenn "vollständig angegeben" ist, versucht der Decoder normalerweise einfach, mit diesem Medientyp zu arbeiten. Wenn "teilweise angegeben" ist, wird versucht, einen "vollständig angegebenen" kompatiblen Betriebsmodus zu finden, mit dem eine Verbindung hergestellt werden kann, die mit dem "teilweise angegebenen" Medientyp konsistent ist.
- Die übliche Methode für den Versuch, einen "vollständig angegebenen" Medientyp für eine Verbindung zu finden, besteht darin, einfach eine Liste aller "vollständig angegebenen" Medientypen zu durchlaufen, die der Ausgabepin unterstützt, der mit dem "teilweise angegebenen" Medientyp kompatibel ist, und versuchen, eine Verbindung mit jedem dieser Medientypen herzustellen, bis dies erfolgreich ist. Der Prozess wäre normalerweise ähnlich, wenn kein AM_MEDIA_TYPE im IPin::Connect-Aufruf enthalten ist, der Ausgabenadel jedoch alle Medientypen überprüfen muss.
Wenn der Decoder überprüfen möchte, ob eine bestimmte AM_MEDIA_TYPE (einschließlich einer Videobeschleunigungs-GUID) vom Downstreameingabepin unterstützt wird, kann er IPin::QueryAccept dieser Pin aufrufen (mit der Videobeschleunigungs-GUID als Untertyp des AM_MEDIA_TYPE), oder er kann einfach versuchen, eine Verbindung mit diesem Pin herzustellen, wie unten in Element 5 beschrieben.
Wenn der Decoder nicht weiß, welche Videobeschleuniger-GUIDs der Downstreameingabepin unterstützt und nicht nur eine bestimmte Kandidaten-Videobeschleuniger-GUID vorschlagen möchte, indem er IPin::QueryAccept des downstream-Eingabepins aufruft, kann der Decoder IAMVideoAccelerator::GetVideoAcceleratorGUIDs aufrufen, um eine Liste der vom Pin unterstützten Videobeschleuniger-GUIDs zu erhalten.
Für bestimmte Videobeschleuniger-GUIDs kann der Decoder iamVideoAccelerator::GetUncompFormatsSupported des Downstreameingabepins aufrufen, um eine Liste der DDPIXELFORMAT-Pixelformate abzurufen, die zum Rendern einer bestimmten Videobeschleunigungs-GUID verwendet werden können. Die zurückgegebene Liste sollte als in einer abnehmenden Präferenzreihenfolge angesehen werden (d. a. mit dem am häufigsten bevorzugten Format zuerst aufgeführt).
Der Decoder ruft IPin::ReceiveConnection des downstream-Eingabepins auf und übergibt diesem eine AM_MEDIA_TYPE mit der richtigen Videobeschleuniger-GUID als Untertyp des Medientyps. Dadurch wird die Verbindung für den Betrieb eingerichtet, einschließlich der Erstellung der unkomprimierten Ausgabeflächen (die anhand der Breite und Höhe in AM_MEDIA_TYPE und der Anzahl der oberflächen zugeordnet werden, die von einem unten beschriebenen Aufruf gefunden werden, und unabhängig davon, welche anderen Informationen der Videobeschleunigung zur Verfügung stehen und zu diesem Zweck verwenden möchte ( z. B. die Videobeschleuniger-GUID selbst). Wenn der nachgeschaltete Eingabepin die Videobeschleunigungs-GUID oder einen anderen Aspekt der Verbindung ablehnt, kann dies dazu führen, dass die IPin::ReceiveConnection fehlschlägt. Wenn IPin::ReceiveConnection fehlschlägt, wird dies in einem zurückgegebenen HRESULT angegeben, und der Decoder kann versuchen, den Aufruf erneut auszuführen, z. B. mit einer neuen Videobeschleunigungs-GUID in der AM_MEDIA_TYPE-Struktur .
[!Hinweis]
Dies ist eine weitere Möglichkeit (und die definitivste Methode) für den Decoder, um zu bestimmen, was vom Downstreameingabepin unterstützt wird– einfach IPin::ReceiveConnection aufrufen und versuchen, eine Verbindung herzustellen, und dann zu überprüfen, ob der Verbindungsversuch erfolgreich war.
Während der IPin::ReceiveConnection ruft der Renderer iamVideoAcceleratorNotify::GetUncompSurfacesInfo des Decoders auf und übergibt die Videobeschleuniger-GUID und eine AMVAUncompBufferInfo-Struktur , um herauszufinden, wie viele nicht komprimierte Oberflächen zugeordnet werden sollen. Der Decoder füllt aus und gibt die Struktur zurück, die die minimale und maximale Anzahl von Oberflächen enthält, die dem jeweiligen Typ zugeordnet werden sollen, sowie eine DDPIXELFORMAT-Struktur , die das Pixelformat der zuzuordnenden Oberflächen beschreibt.
[!Hinweis]
Beim Aufruf von IAMVideoAcceleratorNotify::GetUncompSurfacesInfo wird nichts an den Decoder übergeben, außer der Videobeschleunigungs-GUID.
Der Renderer ruft iamVideoAcceleratorNotify::SetUncompSurfacesInfo des Decoders auf und übergibt an den Decoder die tatsächliche Anzahl der zugewiesenen nicht komprimierten Oberflächen.
Der Renderer ruft iamVideoAcceleratorNotify::GetCreateVideoAcceleratorData des Decoders auf, um alle Daten abzurufen, die zum Initialisieren der Videobeschleunigung erforderlich sind.
Der Decoder ruft IAMVideoAccelerator::GetCompBufferInfo auf und übergibt eine Videobeschleunigungs-GUID, eine AMVAUncompDataInfo-Struktur und die Anzahl komprimierter Puffertypen, um eine Gruppe von AMVACompBufferInfo-Datenstrukturen zurückzugeben, die jedem Typ von komprimiertem Datenpuffer entspricht, der von der Videobeschleuniger-GUID verwendet wird.
- Die AMVAUncompDataInfo-Struktur enthält die Breite und Höhe der decodierten unkomprimierten Daten (in Pixel) und das DDPIXELFORMAT des unkomprimierten Bilds.
- Die zurückgegebenen AMVACompBufferInfo-Datenstrukturen enthalten:
Die Anzahl der komprimierten Puffer, die für den jeweiligen Typ benötigt werden.
Die Breite und Höhe der zu erstellenden Fläche (Felder, die möglicherweise eine tatsächliche Bedeutung haben oder nicht).
Hinweis
Der DirectDraw-Oberflächenzuordnungsvorgang für die komprimierten Puffer sieht derzeit nicht vor, dass die Breite oder Höhe dieser Oberflächen größer oder gleich 2^15 ist, obwohl der Oberflächenzuordnungsaufruf möglicherweise nicht übermäßig fehlschlägt, wenn dieser Grenzwert verletzt wird. Daher könnte der Treiber seine Anforderungen für komprimierten Pufferspeicher strukturieren, um solche extremen Größen zu vermeiden. Anstatt beispielsweise einen Puffer mit width="1" und height="65536" anzufordern, sollte der Treiber einen Puffer von width="1024" und height="64" anfordern.
Die Gesamtanzahl der Bytes, die von der Oberfläche verwendet werden sollen.
Eine Struktur vom Typ DDSCAPS2 , die ein DirectDrawSurface-Objekt definiert und die Funktionen zum Erstellen von Oberflächen zum Speichern komprimierter Daten beschreibt.
Ein DDPIXELFORMAT, das das Pixelformat beschreibt, das zum Erstellen von Oberflächen zum Speichern komprimierter Daten verwendet wird (ein Feld, das möglicherweise eine tatsächliche Bedeutung haben kann oder nicht).
Hinweis
Die Aufrufe des Renderers an einige der IAMVideoAcceleratorNotify-Schnittstellenmethoden des Decoders können (und würden normalerweise) innerhalb des Aufrufs des Decoders an die IPin::ReceiveConnection des Renderers erfolgen. Dies gilt insbesondere für Folgendes:
Hinweis
Um dynamische Formatänderungen zu unterstützen, kann der Decoder auch IPin::ReceiveConnection und andere Oben genannte Methoden aufrufen, während die Filter verbunden sind und ausgeführt werden. Diese Funktion wird bereitgestellt, um dynamische Formatänderungen zu unterstützen (wenn auch nicht in H.263, Anhang P, Sinn - da alle Datasets von Grund auf neu gestartet werden und daher alle Referenzbildinformationen verloren gehen).
Im Folgenden wird die Verwendung von IAMVideoAccelerator während des Betriebs nach der Initialisierung beschrieben:
Für jede unkomprimierte Oberfläche ruft der Decoder IAMVideoAccelerator::BeginFrame auf, um mit der Verarbeitung zum Erstellen des Ausgabebilds zu beginnen. In diesem Fall sendet der Decoder eine AMVABeginFrameInfo-Struktur .
Die AMVABeginFrameInfo-Struktur enthält einen Index für einen Zielpuffer, einen Zeiger auf einige Daten, die nachgeschaltet werden sollen, und einen Zeiger auf eine Stelle, an der die Zugriffstaste einige Daten für den Decoder lesen kann.
HINWEIS 1: Der Zielpufferindex wird von der Zugriffstaste nicht empfangen, da er vom Renderer übersetzt wird, bevor er nachgeschaltet wird.
HINWEIS 2: IAMVideoAccelerator::BeginFrame kann zwischen Aufrufen von IAMVideoAccelerator::EndFrame mehrmals aufgerufen werden.
HINWEIS 3: Es gibt keine Annahme innerhalb des Schnittstellenvorgangs, dass IAMVideoAccelerator::BeginFrame und IAMVideoAccelerator::EndFrame für die Verarbeitung jedes einzelnen Bilds im Bitstream aufgerufen werden müssen.
Was IAMVideoAccelerator::BeginFrame tut, soweit die Schnittstelle betrifft, ist das Erstellen einer Zuordnung innerhalb des Renderers zwischen einem Index und einer nicht komprimierten Oberfläche. Es bietet auch eine Möglichkeit, eine bestimmte Funktion in einem Gerätetreiber aufzurufen (mit Unterstützung einer Möglichkeit, beliebige Daten zwischen dem Decoder und dem Gerätetreiber hin und her zu übergeben).
(Im DirectX VA-Vorgang gibt es jedoch die unten beschriebene Anforderung, dass IAMVideoAccelerator::BeginFrame und IAMVideoAccelerator::EndFrame für die Verarbeitung jedes einzelnen Bilds im Bitstream aufgerufen werden müssen.)
Zum Senden von unkomprimierten Daten an die Beschleunigertaste ruft der Decoder Folgendes auf:
- IAMVideoAccelerator::QueryRenderStatus , um zu bestimmen, ob ein Puffer sicher zum Lesen von oder Schreiben in ist.
- IAMVideoAccelerator::GetBuffer zum Sperren und Abrufen des Zugriffs auf einen angegebenen Puffer (sofern dieser zuvor noch nicht aufgerufen wurde, um diesen Zugriff zu erhalten). GetBuffer kann auch verwendet werden, um eine Kopie des Inhalts des letzten unkomprimierten Ausgabebilds abzurufen, für das IAMVideoAccelerator::BeginFrame aufgerufen wurde, sofern IAMVideoAccelerator::EndFrame für diesen Zielpufferindex nicht aufgerufen wurde. Wenn der DDI eine Render-status von DDERR_WASSTILLDRAWING für den angeforderten Puffer zurückgibt, wird in GetBuffer eine Standbyschleife ausgeführt, bis diese Bedingung aufgehoben ist. Um GetBuffer aufzurufen, benötigt der Decoder einige Informationen aus einer AMVACompBufferInfo-Datenstruktur , die durch Aufrufen von IAMVideoAccelerator::GetCompBufferInfo abgerufen wird.
- IAMVideoAccelerator::Execute , um anzugeben, dass die Daten in einem Satz komprimierter Puffer, wie in einem Array von AMVABUFFERINFO-Datenstrukturen angegeben, verarbeitet werden sollen. Der Funktionscode dwFunction wird in diesem Aufruf an den Treiber übergeben. Ein lpPrivateInputData-Zeiger wird auch an einige Daten übergeben, um downstream zu senden, und ein lpPrivateOutputData-Zeiger wird an eine Stelle übergeben, an der der Downstreamprozess einige Daten für den Decoder lesen kann.
- IAMVideoAccelerator::ReleaseBuffer , um anzugeben, dass der Decoder die Verwendung eines angegebenen Puffers für den Moment abgeschlossen hat und keinen gesperrten Zugriff mehr auf den Puffer benötigt. (Wenn der Decoder den Puffer weiterhin verwenden möchte, kann er IAMVideoAccelerator::ReleaseBuffer für den Moment einfach nicht aufrufen, sodass IAMVideoAccelerator::GetBuffer nicht aufgerufen werden muss, bis der Puffer wirklich nicht mehr verwendet werden soll.) Der Decoder sollte erst in den Puffer schreiben, nachdem Execute aufgerufen wurde, bis QueryRenderStatus angibt, dass der Puffer sicher zum Schreiben ist.
Um die Ausgabeverarbeitung für einen Zielpuffer abzuschließen, ruft der Decoder IAMVideoAccelerator::EndFrame auf. Mit diesem Aufruf können einige beliebige Daten nachgeschaltet werden, und das ist im Wesentlichen alles, was als Ergebnis dieses Aufrufs geschieht. In diesem Aufruf wird kein Zielpufferindex gesendet, sodass der Beschleuniger nicht genau angegeben werden kann, welcher Zielpuffer abgeschlossen ist, es sei denn, dieser Hinweis ist in den übergebenen beliebigen Daten enthalten.
Um einen Frame anzuzeigen, ruft der Decoder IAMVideoAccelerator::D isplayFrame mit dem Index des anzuzeigenden Frames und einer IMediaSample-Struktur mit Start- und Stoppzeitstempeln und relevanten Flags wie dwTypeSpecificFlags in der AM_SAMPLE2_PROPERTIES-Struktur und dwInterlaceFlags in der VIDEOINFOHEADER2-Struktur auf. Der Decoder muss überprüfen, ob alle Dekomprimierungsvorgänge, die sich auf den Inhalt des Frames auswirken, abgeschlossen sind, bevor DisplayFrame aufgerufen wird.
Schließlich sollte der Decoder nach Abschluss der Verarbeitung den Abschluss aller verbleibenden gestarteten Ausgabeframes durch Aufrufen von IAMVideoAccelerator::EndFrame und alle gesperrten Puffer freigeben, indem IAMVideoAccelerator::ReleaseBuffer für jeden nicht veröffentlichten Puffer aufgerufen wird.
Zugehörige Themen