Unterstützung von DXVA 2.0 in Media Foundation
In diesem Thema wird beschrieben, wie DirectX Video Acceleration (DXVA) 2.0 in einer Media Foundation-Transformation (MFT) mithilfe von Microsoft Direct3D 9 unterstützt wird. Insbesondere wird die Kommunikation zwischen dem Decoder und dem Videorenderer beschrieben, der vom Topologielader vermittelt wird. In diesem Thema wird nicht beschrieben, wie die DXVA-Decodierung implementiert wird.
Im restlichen Teil dieses Themas bezieht sich der Begriff Decoder auf den Decoder MFT, der komprimiertes Video empfängt und unkomprimiertes Video ausausgabet. Der Begriff Decodergerät bezieht sich auf eine Hardwarevideobeschleunigung, die vom Grafiktreiber implementiert wird.
Tipp
Informationen zur Videodecodierung von Microsoft Direct3D 11 finden Sie unter Supporting Direct3D 11 Video Decoding in Media Foundation.
Hinweis
Windows Store Müssen Direct3D 11 verwenden.
Hier sind die grundlegenden Schritte, die ein Decoder ausführen muss, um DXVA 2.0 in Media Foundation:
- Öffnen Sie ein Handle für das Direct3D 9-Gerät.
- Suchen sie nach einer DXVA-Decoderkonfiguration.
- Ordnen Sie unkomprimierte Puffer zu.
- Decodieren von Frames.
Diese Schritte werden im weiteren Verlauf dieses Themas ausführlicher beschrieben.
Öffnen eines Direct3D-Gerätehandpunkts
MFT verwendet den Microsoft Direct3D-Geräte-Manager, um ein Handle für das Direct3D 9-Gerät zu erhalten. Führen Sie die folgenden Schritte aus, um das Gerätehand handle zu öffnen:
- Machen Sie das MF _ SA _ D3D _ AWARE-Attribut mit dem Wert TRUE verfügbar. Das Topologielader fragt dieses Attribut ab, indem ESGETRANSFORM::GetAttributes aufruft. Wenn Sie das -Attribut auf TRUE festlegen, wird das Topologielader benachrichtigt, dass das MFT DXVA unterstützt.
- Wenn die Formatierungsaushandlung beginnt, ruft das Topologielader mit der MFT _ MESSAGE _ SET _ D3D _ MANAGER-Nachricht DEN AUFRUF VON DURCHSICHTTransform::P rocessMessage auf. Der ulParam-Parameter ist ein IUnknown-Zeiger auf den Direct3D-Geräte-Manager des Videorenderers. Fragen Sie diesen Zeiger für die IDirect3DDeviceManager9-Schnittstelle ab.
- Rufen Sie IDirect3DDeviceManager9::OpenDeviceHandle auf, um ein Handle für das Direct3D-Gerät des Renderers abzurufen.
- Rufen Sie IDirect3DDeviceManager9::GetVideoService auf, und übergeben Sie das Gerätehand handle. Diese Methode gibt einen Zeiger auf die IDirectXVideoDecoderService-Schnittstelle zurück.
- Speichern Sie die Zeiger und das Gerätehandler zwischen.
Suchen einer Decoderkonfiguration
MFT muss eine kompatible Konfiguration für das DXVA-Decodergerät finden. Führen Sie nach der Validierung des Eingabetyps die folgenden Schritte in der METHODE VEREERTRANSFORM::SetInputType aus:
Rufen Sie IDirectXVideoDecoderService::GetDecoderDeviceGuids auf. Diese Methode gibt ein Array von Decodergeräte-GUIDs zurück.
Schleife durch das Array von Decoder-GUIDs, um diejenigen zu finden, die der Decoder unterstützt. Für einen MPEG-2-Decoder würden Sie beispielsweise nach DXVA2 _ ModeMPEG2 _ MOCOMP, DXVA2 _ ModeMPEG2 _ IDCT oder DXVA2 _ ModeMPEG2 _ VLD suchen.
Wenn Sie eine kandidatenweise Decodergeräte-GUID finden, übergeben Sie die GUID an die IDirectXVideoDecoderService::GetDecoderRenderTargets-Methode. Diese Methode gibt ein Array von Renderzielformaten zurück, die als D3DFORMAT-Werte angegeben werden.
Schleife durch die Renderzielformate, und suchen Sie nach einem Format, das vom Decoder unterstützt wird.
Rufen Sie IDirectXVideoDecoderService::GetDecoderConfigurations auf. Übergeben Sie die gleiche Decodergeräte-GUID zusammen mit einer DXVA2 _ VideoDesc-Struktur, die das vorgeschlagene Ausgabeformat beschreibt. Die -Methode gibt ein Array von DXVA2-ConfigPictureDecode-Strukturen _ zurück. Jede Struktur beschreibt eine mögliche Konfiguration für das Decodergerät. Suchen Sie nach einer Konfiguration, die der Decoder unterstützt.
Store das Format und die Konfiguration des Renderziels.
Geben Sie in der METHODE DURCHSICHTTransform::GetOutputAvailableType basierend auf dem vorgeschlagenen Renderzielformat ein unkomprimiertes Videoformat zurück.
Überprüfen Sie den Medientyp in der METHODE VERTRANSFORM::SetOutputType mit dem Renderzielformat.
Fallback auf Softwaredecodierung
Wenn MFT keine DXVA-Konfiguration finden kann (z. B. wenn der Grafiktreiber nicht über die richtigen Funktionen verfügt), sollte er den Fehlercode MF _ E _ UNSUPPORTED _ D3D _ TYPE aus den Methoden SetInputType und SetOutputType zurückgeben. Das Topologielader antwortet, indem es die MFT _ MESSAGE SET _ _ D3D _ MANAGER-Nachricht mit dem Wert NULL für den ulParam-Parameter sendet. Der MFT sollte seinen Zeiger auf die IDirect3DDeviceManager9-Schnittstelle frei geben. Der Medientyp wird dann vom Topologielader neu ausgehandelt, und MFT kann die Softwaredecodierung verwenden.
Zuordnen von unkomprimierten Puffern
In DXVA 2.0 ist der Decoder dafür verantwortlich, Direct3D-Oberflächen als unkomprimierte Videopuffer zu verwenden. Der Decoder sollte 3 Oberflächen zuordnen, die der EVR für das Deinterlacing verwenden kann. Diese Zahl ist fest, da Media Foundation evr keine Möglichkeit bietet, anzugeben, wie viele Oberflächen der Grafiktreiber für das Deinterlacing benötigt. Drei Oberflächen sollten für jeden Treiber ausreichend sein.
Legen Sie in der METHODE VERFORMTransform::GetOutputStreamInfo das Flag MFT OUTPUT STREAM PROVIDES _ _ _ _ SAMPLES in der MFT _ OUTPUT STREAM _ _ INFO-Struktur fest. Dieses Flag benachrichtigt die Mediensitzung, dass MFT eigene Ausgabebeispiele zuteilen.
Rufen Sie zum Erstellen der Oberflächen IDirectXVideoAccelerationService::CreateSurface auf. (Die IDirectXVideoDecoderService-Schnittstelle erbt diese Methode von IDirectXVideoAccelerationService.) Sie können dies in SetInputType nachdem Suchen des Renderzielformats tun.
Rufen Sie für jede Oberfläche MFCreateVideoSampleFromSurface auf, um ein Medienbeispiel für die Oberfläche zu erstellen. Die -Methode gibt einen Zeiger auf die NSSAMPLE-Schnittstelle zurück.
Decodierung
Rufen Sie zum Erstellen des Decodergeräts IDirectXVideoDecoderService::CreateVideoDecoder auf. Die -Methode gibt einen Zeiger auf die IDirectXVideoDecoder-Schnittstelle des Decodergeräts zurück.
Die Decodierung sollte innerhalb der METHODE 10::P ROCTransform::P Output erfolgen. Rufen Sie in jedem Frame IDirect3DDeviceManager9::TestDevice auf, um das Gerätehandchen zu testen. Wenn das Gerät geändert wurde, gibt die Methode DXVA2 _ E NEW VIDEO DEVICE _ _ _ zurück. Gehen Sie in diesem Fall wie folgt vor:
- Schließen Sie das Gerätehandle, indem Sie IDirect3DDeviceManager9::CloseDeviceHandle aufrufen.
- Geben Sie die Zeiger IDirectXVideoDecoderService und IDirectXVideoDecoder frei.
- Öffnen Sie ein neues Gerätehand handle.
- Aushandeln einer neuen Decoderkonfiguration, wie weiter oben auf dieser Seite unter "Finding a Decoder Configuration" (Suchen einer Decoderkonfiguration) beschrieben.
- Erstellen Sie ein neues Decodergerät.
Unter der Annahme, dass das Gerätehandy gültig ist, funktioniert der Decodierungsprozess wie folgt:
- Hier erhalten Sie eine verfügbare Oberfläche, die derzeit nicht verwendet wird. (Anfänglich sind alle Oberflächen verfügbar.)
- Fragen Sie das Medienbeispiel für die BENUTZEROBERFLÄCHETrackedSample-Schnittstelle ab.
- Rufen Sie DIEDOKTrackedSample::SetAllocator auf, und stellen Sie einen Zeiger auf die DURCHDNASYNCCallback-Schnittstelle bereit, die vom Decoder implementiert wird. Wenn der Videorenderer das Beispiel frei gibt, wird der Rückruf des Decoders aufgerufen.
- Rufen Sie IDirectXVideoDecoder::BeginFrame auf.
- Führen Sie die folgenden Schritte mindestens einmal aus:
- Rufen Sie IDirectXVideoDecoder::GetBuffer auf, um einen DXVA-Decoderpuffer zu erhalten.
- Füllen Sie den Puffer aus.
- Rufen Sie IDirectXVideoDecoder::ReleaseBuffer auf.
- Rufen Sie IDirectXVideoDecoder::Execute auf, um die Decodierungsvorgänge für den Frame auszuführen.
DXVA 2.0 verwendet dieselben Datenstrukturen wie DXVA 1.0 für Decodierungsvorgänge. Für den ursprünglichen Satz von DXVA-Profilen (für H.261, H.263 und MPEG-2) werden diese Datenstrukturen in der DXVA 1.0-Spezifikation beschrieben.
Innerhalb jedes BeginFrame Execute-Aufrufpaarskönnen Sie GetBuffer mehrmals aufrufen, jedoch nur einmal für jeden / DXVA-Puffertyp. Wenn Sie ihn zweimal mit dem gleichen Puffertyp aufrufen, überschreiben Sie die Daten.
Verwenden Sie den Rückruf der SetAllocator-Methode (Schritt 3), um zu verfolgen, welche Beispiele derzeit verfügbar sind und welche verwendet werden.