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, die vom Topologieladeprogramm vermittelt wird. In diesem Thema wird nicht beschrieben, wie die DXVA-Decodierung implementiert wird.

Im weiteren Verlauf dieses Themas bezieht sich der Begriff Decoder auf den Decoder MFT, der komprimierte Videos empfängt und unkomprimierte Videos ausgibt. Der Begriff Decodergerät bezieht sich auf einen hardwarebasierten Videobeschleuniger, der vom Grafiktreiber implementiert wird.

Tipp

Informationen zur Microsoft Direct3D 11-Videocodierung finden Sie unter Unterstützung der Direct3D 11-Videodecodierung in Media Foundation.

 

Hinweis

Windows Store-Apps müssen Direct3D 11 verwenden.

 

Hier sind die grundlegenden Schritte, die ein Decoder ausführen muss, um DXVA 2.0 in Media Foundation zu unterstützen:

  1. Öffnen Sie ein Handle für das Direct3D 9-Gerät.
  2. Suchen Sie nach einer DXVA-Decoderkonfiguration.
  3. Ordnen Sie nicht komprimierte Puffer zu.
  4. Decodieren von Frames.

Diese Schritte werden im weiteren Verlauf dieses Themas ausführlicher beschrieben.

Öffnen eines Direct3D-Gerätehandles

Der MFT verwendet den Microsoft Direct3D-Geräte-Manager, um ein Handle für das Direct3D 9-Gerät abzurufen. Führen Sie zum Öffnen des Gerätehandles die folgenden Schritte aus:

  1. Machen Sie das attribut MF_SA_D3D_AWARE mit dem Wert TRUE verfügbar. Das Topologieladeprogramm fragt dieses Attribut durch Aufrufen von IMFTransform::GetAttributes ab. Durch Festlegen des Attributs auf TRUE wird der Topologieladeer benachrichtigt, dass der MFT DXVA unterstützt.
  2. Wenn die Formatverhandlung beginnt, ruft der Topologieladeprogramm IMFTransform::P rocessMessage mit der MFT_MESSAGE_SET_D3D_MANAGER-Nachricht 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.
  3. Rufen Sie IDirect3DDeviceManager9::OpenDeviceHandle auf, um ein Handle für das Direct3D-Gerät des Renderers abzurufen.
  4. Rufen Sie IDirect3DDeviceManager9::GetVideoService auf, und übergeben Sie das Gerätehandle. Diese Methode gibt einen Zeiger auf die IDirectXVideoDecoderService-Schnittstelle zurück.
  5. Zwischenspeichern der Zeiger und des Gerätehandles.

Suchen einer Decoderkonfiguration

Der MFT muss eine kompatible Konfiguration für das DXVA-Decodergerät finden. Führen Sie die folgenden Schritte in der IMFTransform::SetInputType-Methode aus, nachdem Sie den Eingabetyp überprüft haben:

  1. Rufen Sie IDirectXVideoDecoderService::GetDecoderDeviceGuids auf. Diese Methode gibt ein Array von Decodergeräte-GUIDs zurück.

  2. Durchlaufen Sie das Array der Decoder-GUIDs, um die vom Decoder unterstützten zu finden. Für einen MPEG-2-Decoder würden Sie beispielsweise nach DXVA2_ModeMPEG2_MOCOMP, DXVA2_ModeMPEG2_IDCT oder DXVA2_ModeMPEG2_VLD suchen.

  3. Wenn Sie eine Kandidaten-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 sind.

  4. Durchlaufen Sie die Renderzielformate, und suchen Sie nach einem vom Decoder unterstützten Format.

  5. 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 vom Decoder unterstützt wird.

  6. Speichern Sie das Renderzielformat und die Konfiguration.

Geben Sie in der IMFTransform::GetOutputAvailableType-Methode basierend auf dem vorgeschlagenen Renderzielformat ein nicht komprimiertes Videoformat zurück.

Überprüfen Sie in der IMFTransform::SetOutputType-Methode den Medientyp mit dem Renderzielformat.

Fallback zur Softwaredecodierung

Wenn der MFT keine DXVA-Konfiguration finden kann (z. B. wenn der Grafiktreiber nicht über die richtigen Funktionen verfügt), sollte er den Fehlercode zurückgeben, der von den Methoden SetInputType und SetOutputTypeMF_E_UNSUPPORTED_D3D_TYPE. Das Topologieladeprogramm antwortet, indem die MFT_MESSAGE_SET_D3D_MANAGER Nachricht mit dem Wert NULL für den ulParam-Parameter gesendet wird. Der MFT sollte seinen Zeiger auf die IDirect3DDeviceManager9-Schnittstelle freigeben. Der Topologieladeprogramm verhandelt dann den Medientyp neu, und der MFT kann die Softwaredecodierung verwenden.

Zuweisung nicht komprimierter Puffer

In DXVA 2.0 ist der Decoder für die Zuweisung von Direct3D-Oberflächen zur Verwendung als unkomprimierte Videopuffer verantwortlich. Der Decoder sollte 3 Oberflächen zuordnen, die der EVR zum Deinterlacing verwenden kann. Diese Zahl ist behoben, da Media Foundation dem EVR keine Möglichkeit bietet, anzugeben, wie viele Oberflächen der Grafiktreiber für die Deinterlacing benötigt. Drei Oberflächen sollten für jeden Fahrer ausreichend sein.

Legen Sie in der IMFTransform::GetOutputStreamInfo-Methode das MFT_OUTPUT_STREAM_PROVIDES_SAMPLES-Flag in der MFT_OUTPUT_STREAM_INFO-Struktur fest. Dieses Flag benachrichtigt die Mediensitzung, dass der MFT eigene Ausgabebeispiele zuordnet.

Um die Oberflächen zu erstellen, rufen Sie IDirectXVideoAccelerationService::CreateSurface auf. (Die IDirectXVideoDecoderService-Schnittstelle erbt diese Methode von IDirectXVideoAccelerationService.) Sie können dies in SetInputType tun, nachdem Sie das Renderzielformat gefunden haben.

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 IMFSample-Schnittstelle zurück.

Decodierung

Um das Decodergerät zu erstellen, rufen Sie IDirectXVideoDecoderService::CreateVideoDecoder auf. Die -Methode gibt einen Zeiger auf die IDirectXVideoDecoder-Schnittstelle des Decodergeräts zurück.

Die Decodierung sollte innerhalb der METHODE IMFTransform::P rocessOutput erfolgen. Rufen Sie für jeden Frame IDirect3DDeviceManager9::TestDevice auf, um das Gerätehandle zu testen. Wenn sich das Gerät geändert hat, gibt die Methode DXVA2_E_NEW_VIDEO_DEVICE zurück. Gehen Sie in diesem Fall wie folgt vor:

  1. Schließen Sie das Gerätehandle, indem Sie IDirect3DDeviceManager9::CloseDeviceHandle aufrufen.
  2. Lassen Sie die Zeiger IDirectXVideoDecoderService und IDirectXVideoDecoder frei.
  3. Öffnen Sie ein neues Gerätehandle.
  4. Verhandeln Sie eine neue Decoderkonfiguration, wie weiter oben auf dieser Seite unter "Suchen einer Decoderkonfiguration" beschrieben.
  5. Erstellen Sie ein neues Decodergerät.

Wenn das Gerätehandle gültig ist, funktioniert der Decodierungsprozess wie folgt:

  1. Rufen Sie eine verfügbare Oberfläche ab, die derzeit nicht verwendet wird. (Zunächst sind alle Oberflächen verfügbar.)
  2. Fragen Sie das Medienbeispiel für die IMFTrackedSample-Schnittstelle ab.
  3. Rufen Sie IMFTrackedSample::SetAllocator auf, und stellen Sie einen Zeiger auf die vom Decoder implementierte IMFAsyncCallback-Schnittstelle bereit. Wenn der Videorenderer das Beispiel freigibt, wird der Rückruf des Decoders aufgerufen.
  4. Rufen Sie IDirectXVideoDecoder::BeginFrame auf.
  5. Führen Sie mindestens ein Mal die folgenden Schritte aus:
    1. Rufen Sie IDirectXVideoDecoder::GetBuffer auf, um einen DXVA-Decoderpuffer zu erhalten.
    2. Füllen Sie den Puffer.
    3. Rufen Sie IDirectXVideoDecoder::ReleaseBuffer auf.
    4. 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.

In jedem Paar von BeginFrame/Execute-Aufrufen können Sie GetBuffer mehrmals aufrufen, aber nur einmal für jeden Typ von DXVA-Puffer. Wenn Sie es zweimal mit demselben Puffertyp aufrufen, überschreiben Sie die Daten.

Verwenden Sie den Rückruf der SetAllocator-Methode (Schritt 3), um nachzuverfolgen, welche Beispiele derzeit verfügbar sind und welche verwendet werden.

DirectX VideoBeschleunigung 2.0

Media Foundation-Transformationen