Peering

Peering / Blog

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.

Ein Mac-Desktop mit geöffnetem Code-Editor, live auf ein iPhone mit Peering gestreamt.
Das Bild auf dem iPhone ist ein kodierter Videostream, keine Folge von Screenshots.

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:

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.