So streamt Peering den Bildschirm deines Macs auf dein iPhone
Ein Remote-Desktop ist ein Videostream mit einer ungewöhnlichen Anforderung: Wer zuschaut, steuert auch. Jede Entscheidung unten folgt daraus, diese Schleife kurz zu halten.
Aufnahme: das Bild beim System anfordern
Die Mac-App holt sich Bilder über Apples ScreenCaptureKit. Quelle kann ein ganzes Display sein, alle Fenster einer App oder ein einzelnes Fenster, und du kannst zwischen ihnen wechseln, ohne die Verbindung zu trennen. Deshalb fragt macOS beim ersten Mal auch nach der Berechtigung „Bildschirmaufnahme“: Ohne sie kann der Mac nur ein schwarzes Bild liefern.
Kodierung: geringe Latenz, keine Umsortierung
Die Bilder gehen an Apples VideoToolbox-Encoder auf dem Mac, als H.264 oder HEVC, je nachdem, was das iPhone dekodieren kann. Die Einstellungen sind das Gegenteil von dem, was ein Streamingdienst nutzt:
- Keine B-Frames. Ein B-Frame braucht ein Bild aus der Zukunft, sie zu nutzen heißt also, Bilder zurückzuhalten. Ohne sie ist die Dekodierreihenfolge die Anzeigereihenfolge, und nichts wartet.
- Ratenkontrolle für niedrige Latenz. Der Encoder gibt seine Bits aus, während er arbeitet, statt vorauszuschauen.
- Mindestens alle zwei Sekunden ein Keyframe, und sofort, wenn ein neuer Betrachter dazukommt, fortsetzt oder die Quelle wechselt, damit ein verlorenes Bild schnell heilt.
- Eine Bitrate, die mit dem Bildschirm skaliert. Standardmäßig ist es die Pixelzahl mal Bildrate mal 0,12, begrenzt auf 4 bis 30 Mbit/s, bei standardmäßig 60 Bildern pro Sekunde.
Die Einrichtungsdaten des Decoders (die Parametersätze) werden einmal als eigene Nachricht gesendet und nicht in jedem Bild wiederholt. Ein iPhone, das mitten im Stream dazukommt, erhält diese Nachricht und dann einen Keyframe.
Senden: verwerfbare Bilder, geschützte Keyframes
Jedes Bild reist mit einem kleinen 25-Byte-Header: ob es ein Keyframe ist, seine Größe in Pixeln und ein Anzeigezeitpunkt. Auf einer Relay- oder Direktverbindung wird es in Datagramme von etwa 1.080 Byte zerlegt, jedes versiegelt mit ChaCha20-Poly1305 und einem Schlüssel, den nur die beiden Geräte kennen. Ein Zähler in jedem Datagramm speist ein Wiederholungsfenster mit 64 Einträgen, sodass ein mitgeschnittenes Paket nicht später erneut abgespielt werden kann.
Die Regel bei Überlast ist schlicht: Video darf verworfen werden, Keyframes nicht. Ist ein neues Bild fertig, während ein altes noch auf das Senden wartet, wird das alte ersetzt, außer dass ein nicht zugestellter Keyframe nie durch ein gewöhnliches Bild ersetzt wird. Den Bildschirm so zu zeigen, wie er jetzt ist, zählt mehr, als jedes Bild zu zeigen, das es je gab.
In einem Heimnetz reist das Bild stattdessen über eine eigene TCP-Verbindung, wo das Netzwerk
zuverlässig genug ist, dass dieselbe Regel selten greifen muss. Jeder Socket setzt TCP_NODELAY.
Das Standardverhalten, kleine Schreibvorgänge zu bündeln, kostet an jeder Station Dutzende Millisekunden, was
bei einem Download unsichtbar ist und beim Bewegen eines Cursors sehr deutlich.
Wiederherstellung: Verlust in Bildqualität bezahlen, nicht in Latenz
UDP sendet nichts erneut, ein verlorenes Datagramm bedeutet also ein beschädigtes Bild. Das iPhone wartet nicht darauf. Es dekodiert weiter, und der Schaden verschwindet beim nächsten Keyframe, höchstens zwei Sekunden später. Wenn dir nach einem schlechten Stück WLAN eine Verschmierung auffällt, ist es genau das. Das Bild anzuhalten und fortzusetzen erzwingt sofort einen Keyframe.
Liefert der schnelle Weg gar nichts mehr, fällt der Stream mit niedrigerer Bitrate auf die Steuerverbindung zurück, wie der Beitrag zur Verbindung beschreibt, und kehrt zurück, sobald der schnelle Weg wieder funktioniert.
Anzeige: ans iPhone anpassen, nicht an den Mac
Das iPhone wählt eine Qualitätsstufe und kann weniger Bilder pro Sekunde anfordern, was der Mac auf einen sinnvollen Bereich begrenzt. Die App kann den ganzen Desktop auf den Bildschirm einpassen oder ihn füllen lassen und sogar beim Mac ein virtuelles Display in der Form des iPhones anfordern, damit ein Monitor im Querformat nicht in einen Hochformat-Bildschirm gequetscht wird. Tipper auf das Bild laufen in die Gegenrichtung, worum es in So wird aus einem Tippen ein Klick geht.
Fragen
Welchen Videocodec nutzt Peering?
H.264 oder HEVC, auf dem Mac mit VideoToolbox kodiert, ohne B-Frames und mit Einstellungen für niedrige Latenz. Das iPhone teilt dem Mac mit, welchen es dekodieren kann.
Warum verschmiert das Bild manchmal kurz?
Ein verlorenes Netzwerkpaket beschädigt ein Bild, und das Bild heilt beim nächsten Keyframe, der mindestens alle zwei Sekunden kommt. Peering nimmt lieber eine kurze Verschmierung in Kauf, als auf eine erneute Übertragung zu warten.