Melden von Miracast-Codierungsblöcken und Statistiken auf Windows 8.1
Hinweis
Ab Windows 10 (WDDM 2.0) wird das Betriebssystem mit einem integrierten Miracast-Stapel ausgeliefert, der auf jeder GPU funktionieren kann. Informationen zum Microsoft Miracast-Stapel und zu den Anforderungen an Treiber und Hardware zur Unterstützung von Miracast-Displays ab Windows 10 finden Sie in der folgenden Dokumentation:
Erstellen von erstklassigen drahtlosen Projektionslösungen mit Windows 10
Die relevante WHLK-Dokumentation unter Device.Graphics.WDDM13.DisplayRender.WirelessDisplay
Treiberentwickler sollten keinen benutzerdefinierten Miracast-Stapel mehr implementieren. Microsoft kann die Unterstützung für benutzerdefinierte Miracast-Stapel in einer zukünftigen Version von Windows entfernen.
Auf Windows 8.1 kann die Anzeigehardware jeden Videoframe verarbeiten, der über einen Miracast-Funkanzeigelink gesendet wird, indem sie den Frame in mehrere Teile aufteilt oder Blöcke codiert. Jeder Block verfügt über eine eindeutige Block-ID, die aus der Framenummer und der Frameteilnummer (oder slice) generiert wird. Jedem Block, der sich auf dasselbe Desktopframeupdate bezieht, muss die gleiche Framenummer zugewiesen werden.
Berichterstellung für Die Verarbeitung von Blockblöcken
Ein Treiber kann einen Frame codieren, der über eine Miracast-Drahtlosverbindung gesendet werden soll, entweder in mehreren Verarbeitungsschritten (z. B. beim Trennen der Farbkonvertierung von der Codierung) oder in einem einzelnen Schritt. Jedem Verarbeitungsschritt sollte innerhalb des Frames eine eindeutige Frameteilnummer zugewiesen werden.
Entweder der Miracast-Benutzermodustreiber oder der Anzeigeminiporttreiber muss das Betriebssystem jedes Mal benachrichtigen, wenn Folgendes gilt:
- Die Hardware hat einen Verarbeitungsschritt für einen Frame abgeschlossen.
- Unmittelbar bevor jeder Teil des Frames an das Netzwerk gesendet wird.
Es wird davon ausgegangen, dass die Zeit eines bestimmten gemeldeten Verarbeitungsschritts der Zeitpunkt ist, zu dem das Ereignis an das Betriebssystem gemeldet wurde. Daher ist es wichtig, die Phasen so schnell wie möglich zu melden.
Das Betriebssystem unternimmt keine andere Aktion, als diese Ereignisse mithilfe der ETW-Funktion (Event Tracing for Windows) auf Kernelebene zu protokollieren. Diese Informationen sind dennoch wichtig, um Leistungsprobleme zu messen und zu untersuchen.
Ein Treiber kann die Benachrichtigung mithilfe einer der folgenden Möglichkeiten bereitstellen:
- Der Miracast-Benutzermodustreiber ruft die ReportStatistic-Rückruffunktion auf, um Details mit dem MIRACAST_STATISTIC_TYPE_CHUNK_PROCESSING_COMPLETE-Typ oder mit MIRACAST_STATISTIC_TYPE_CHUNK_SENT zu melden, um anzugeben, dass der Block zur Übertragung an den Netzwerkstapel gesendet wird.
- Der Anzeigeminiporttreiber meldet Details der Blockverarbeitung mit dem DXGK_INTERRUPT_MICACAST_CHUNK_PROCESSING_COMPLETE Interrupttyp, obwohl dieser Bericht nur zur Unterbrechungszeit erstellt werden kann. Zusätzlich zur Protokollierung der Blockinformationen wird ein Blockpaket erstellt und in die Warteschlange gestellt, damit der Miracast-Benutzermodustreiber es abrufen kann, indem die Rückruffunktion GetNextChunkData aufgerufen wird.
- Der Anzeigeminiporttreiber ruft die DxgkCbReportChunkInfo-Rückruffunktion auf jeder IRQL-Ebene auf. Diese Funktion protokolliert nur die Blockinformationen und stellt keine Blöcke in die Warteschlange.
Die gleichen Framenummern und Teilenummern sollten verwendet werden, wenn das Desktopimage nicht aktualisiert wird, der Treiber das Desktopimage jedoch erneut codieren muss, um die Qualität zu verbessern. Die Leistungstools lösen das zweite codierende vollständige Ereignis für denselben Frame und die gleiche Teilenummer aus, was angibt, dass eine zweite Codierung desselben Frames ausgeführt wurde.
Der letzte Slice jedes Frames muss die Frameteilnummer 0 aufweisen, was den letzten Slice des Frames für Leistungstools angibt.
Wenn die Pixelpipeline die Codierung ausführt, sollten alle angeforderten Flipvorgänge in einem VSync-Intervall nicht gemeldet werden, bevor die Codierung den Zugriff auf die primäre Oberfläche abgeschlossen hat, um eine korrekte Synchronisierung der primären Oberfläche sicherzustellen. Dieses Verhalten verhindert, dass der Referenten auf der primären Oberfläche gerendert wird, während die Codierungs-Engine davon liest.
Der Miracast-Benutzermodustreiber sollte das Betriebssystem in verschiedenen Phasen der Verarbeitung des Frames informieren:
Startframe, Blocktyp MIRACAST_CHUNK_TYPE_FRAME_START
Stellt den Punkt dar, an dem das Betriebssystem den Treiber auffragt, den neuen Desktopframe anzuzeigen. Obwohl technisch gesehen der Miracast-Benutzermodustreiber diese Phase melden könnte, ist der Beginn der Verarbeitung eines neuen Frames immer mit dem Anzeigeminiporttreiber verbunden und sollte daher von diesem Treiber gemeldet werden.
Farbkonvertierung abgeschlossen, Blocktyp MIRACAST_CHUNK_TYPE_COLOR_CONVERT_COMPLETE
Einige Lösungen verfügen über separate Farbkonvert- und Codierungsphasen. In solchen Lösungen sollte das Ereignis für die vollständige Verarbeitung der Farbkonvertieren so schnell wie möglich gemeldet werden, und der Treiber sollte die DXGK_MIRACAST_CHUNK_INFO verwenden. ProcessingTime-Member , um die Zeit zu melden, die die Hardware zum Ausführen des Vorgangs benötigt hat. Wenn der gesamte Frame auf einmal und nicht in Slices farblich konvertiert wird, sollte die Teilenummer 0 sein.
Codieren des vollständigen Blocktyps MIRACAST_CHUNK_TYPE_ENCODE_COMPLETE
Gibt an, dass die H.264-Codierung abgeschlossen wurde. Die Member ProcessingTime und EncodeRate der DXGK_MIRACAST_CHUNK_INFO Struktur sollten abgeschlossen sein.
Frame send, Aufruf von ReportStatistic mithilfe von MIRACAST_STATISTIC_TYPE_CHUNK_SENT
Gibt an, dass der Miracast-Benutzermodustreiber das Datenpaket für diese Frame-/Teilenummer zur Übertragung an die Netzwerk-API senden wird. Wenn die Daten für diesen Frame/Teil mithilfe mehrerer Aufrufe an die Netzwerk-API gesendet werden, sollten sie nur kurz vor dem Senden des ersten Pakets protokolliert werden. Der Aufruf sollte kurz vor dem Aufrufen der Netzwerk-API erfolgen. Dieses Timing ist wichtig, denn wenn die Netzwerk-API Aufrufe blockiert, soll diese blockierte Zeit nicht mit der Verarbeitung des Frames im Grafikstapel gezählt werden.
Gelöschter Frame, Blocktyp MIRACAST_CHUNK_TYPE_FRAME_DROPPED
Wenn der Treiber zu irgendeinem Zeitpunkt entscheidet, dass er die Verarbeitung des Frames/Teils nicht abgeschlossen und an die Senke sendet, sollte er den gelöschten Frame melden. In diesem Kontext gilt ein Frame nur dann als gelöscht, wenn der Treiber tatsächlich mit der Verarbeitung begonnen hat, indem er MIRACAST_CHUNK_TYPE_FRAME_START protokolliert. Wenn ein Treiber berechnet, dass er diesen Frame ohne Verarbeitung überspringen wird, kann er MIRACAST_CHUNK_TYPE_FRAME_DROPPED protokollieren, ohne MIRACAST_CHUNK_TYPE_FRAME_START zu protokollieren.
Treiberdefinierter Blocktyp MIRACAST_CHUNK_TYPE_ENCODE_DRIVER_DEFINED_1 oder _2
Diese Blocktypen sind verfügbar, um die Leistung eines Szenarios zu verstehen. Beispiele hierfür sind:
- Der Treiber verwendet diese Typen, um anzugeben, dass für diesen Frame ein I-Frame erstellt wurde.
- Der Treiber protokolliert ein weiteres Paket, nachdem der letzte Slice des Frames an Netzwerk-APIs gesendet wurde, die die Gesamtgröße des codierten Frames enthielten.
Beispiele für die Framefarbkonvertierung
Die folgenden Beispiele zeigen, wie die Framefarbe konvertiert wird und wie der Anzeigeminiporttreiber den Abschluss der Farbkonvertierung meldet.
Tabellenverweise auf die Member der MIRACAST_CHUNK_INFO Struktur sind:
ChunkType ist ein MIRACAST_CHUNK_TYPE_XXX-Wert .
FrameNumber und PartNumber sind Mitglieder der ChunkId-Union .
ProcessingTime ist die Zeit in Mikrosekunden.
Codiertrate ist in Kilobit pro Sekunde.
MIRACAST_STATISTIC_TYPE_CHUNK_SENT wird in Verarbeitungsphasen mit Aufrufen von ReportStatistic verwendet.
Melden eines einzelnen Frames ohne Verwendung von Slices
Verarbeitungsphase | ChunkType | FrameNumber | PartNumber | ProcessingTime | EncodeRate |
---|---|---|---|---|---|
Starten der Verarbeitung von Frame | FRAME_START | 101 | 0 | 0 | 0 |
Die Farbkonvertierung ist abgeschlossen | COLOR_CONVERT_COMPLETE | 101 | 0 | 950 | 0 |
Codieren ist abgeschlossen | ENCODE_COMPLETE | 101 | 0 | 1042 | 15000 |
Kurz vor dem Aufruf zum Senden von Daten an das Netzwerk ReportStatistic-Aufruf | – | 101 (Wert von ChunkSent.ChunkId.FrameNumber) | 0 (Wert von ChunkSent.ChunkId.PartNumber) | – | – |
Melden eines einzelnen Frames, verarbeitet mithilfe von Slices
Verarbeitungsphase | ChunkType | FrameNumber | PartNumber | ProcessingTime | EncodeRate |
---|---|---|---|---|---|
Starten der Verarbeitung des Frames | FRAME_START | 101 | 0 | 0 | 0 |
Die Farbkonvertierung ist abgeschlossen. | COLOR_CONVERT_COMPLETE | 101 | 0 | 950 | 0 |
Codieren von Slice 1 ist abgeschlossen | ENCODE_COMPLETE | 101 | 1 | 1042 | 15000 |
Codieren von Slice 2 ist abgeschlossen | ENCODE_COMPLETE | 101 | 0 | 400 | 15000 |
Kurz vor dem Aufruf zum Senden von Daten in Segment 1 an den ReportStatistic-Netzwerkaufruf | – | 101 (Wert von ChunkSent.ChunkId.FrameNumber für Slice 1) | 1 (Wert von ChunkSent.ChunkId.PartNumber für Slice 1) | – | – |
Kurz vor dem Aufruf zum Senden von Daten in Segment 2 an den ReportStatistic-Netzwerkaufruf | – | 101 (Wert von ChunkSent.ChunkId.FrameNumber für Slice 2) | 0 (Wert von ChunkSent.ChunkId.FrameNumber für Slice 2) | – | – |
Melden eines ursprünglichen Frames, verarbeitet und dann neu codiert ohne Verwendung von Slices
Verarbeitungsphase | ChunkType | FrameNumber | PartNumber | ProcessingTime | EncodeRate |
---|---|---|---|---|---|
Starten der Verarbeitung des Frames | FRAME_START | 101 | 0 | 0 | 0 |
Die Farbkonvertierung ist abgeschlossen. | COLOR_CONVERT_COMPLETE | 101 | 0 | 950 | 0 |
Codieren ist abgeschlossen | ENCODE_COMPLETE | 101 | 0 | 1042 | 15000 |
Kurz vor dem Aufruf zum Senden von Daten für den ursprünglichen Frame an den ReportStatistic-Netzwerkaufruf | – | 101 (Wert von ChunkSent.ChunkId.FrameNumber) | 0 (Wert von ChunkSent.ChunkId.PartNumber) | – | – |
Die erneute Codierung ist abgeschlossen. | ENCODE_COMPLETE | 101 | 0 | 500 | 15000 |
Kurz vor dem Aufruf zum Senden von Daten für den neu codierten Frame an das Netzwerk ReportStatistic | – | 101 (Wert von ChunkSent.ChunkId.FrameNumber) | 0 (Wert von ChunkSent.ChunkId.PartNumber) | – | – |
Melden von Protokollereignissen
Wenn der Miracast-Benutzermodustreiber Protokollereignisse meldet, indem er die ReportStatistic-Funktion mit MIRACAST_STATISTIC_DATAaufruft. StatisticType ist auf MIRACAST_STATISTIC_TYPE_EVENT festgelegt, das Betriebssystem protokolliert das Ereignis, führt jedoch keine andere Aktion aus. Dennoch sind diese Ereignisse für die Diagnose und Leistungsuntersuchung von Nutzen.
Die MIRACAST_PROTOCOL_EVENT-Enumeration enthält mögliche Protokollereignistypen, die gemeldet werden können.
Melden von Protokollfehlern
Während eine verbundene Miracast-Sitzung ausgeführt wird und ein Miracast-Benutzermodustreiber einen Fehler erkennt, sollte er die Rückruffunktion ReportSessionStatus mit entsprechenden MIRACAST_STATUS Fehlerstatusinformationen im MiracastStatus-Parameter aufrufen. Die Betriebssitzung zerstört die Sitzung immer, wenn ein Fehler gemeldet wird.
Obwohl das Betriebssystem nur den Parameter ReportSessionStatusStatus für die Diagnose protokolliert und keine Aktion basierend auf seinem Wert ergreift, sollte der Treiber diesen Parameter verwenden, um zwischen verschiedenen Fehlerursachen zu unterscheiden.